当前位置: 首页 > news >正文

网站服务器送一年德州做网站哪家好

网站服务器送一年,德州做网站哪家好,建设通网站会员免费吗,化妆品网页设计论文一:实现 方式一:继承AbstractRoutingDataSource使用自定义注解实现 环境:springboot3 MyBatis3 mysql-connector8 DataSourceKeyEnum枚举类 有几个数据源就配置几个枚举类,和数据源数量一一对应 class DataSourceKeyEnum{D…

一:实现

方式一:继承AbstractRoutingDataSource使用自定义注解实现

环境:springboot3 + MyBatis3 + mysql-connector8

DataSourceKeyEnum枚举类

有几个数据源就配置几个枚举类,和数据源数量一一对应

class DataSourceKeyEnum{DEFAULT,SLAVE
}

DataSourceAnnotation注解

用来标记在Service方法或Mapper上,用于辅助AOP切换数据源操作。

@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DataSourceAnnotation {DataSourceKeyEnum value() default DataSourceKeyEnum.DEFAULT;}

AbstractRoutingDataSource 的作用

AbstractRoutingDataSource的核心功能是根据用户定义的规则,动态决定在特定的操作中使用哪个数据源。这通常是通过重写determineCurrentLookupKey方法来实现的,该方法用于确定当前线程应该使用哪个数据源的键。

public class DynamicDataSource extends AbstractRoutingDataSource {/***  MyBatis内部根据实现AbstractRoutingDataSource类的determineCurrentLookupKey实现数据源的动态路由*/@Overrideprotected Object determineCurrentLookupKey() {return DynamicDataSourceContextHolder.getDataSourceType();}/***  静态内部类,用于从线程中获取当前要使用的数据源*/public static class DynamicDataSourceContextHolder {private static final ThreadLocal<DataSourceKeyEnum> contextHolder = new ThreadLocal<>();public static DataSourceKeyEnum getDataSourceType() {return contextHolder.get();}public static void setDataSourceType(DataSourceKeyEnum dataSourceKey) {if (dataSourceKey == null) {dataSourceKey = DataSourceKeyEnum.DEFAULT;}contextHolder.set(dataSourceKey);}public static void clearDataSourceType() {contextHolder.remove();}}
}

DataSourceConfig数据源配置类

环境配置

spring.datasource.default.driverClassName=com.mysql.cj.jdbc.Driver
spring.datasource.default.jdbcUrl=jdbc:mysql://xxxxxx/mybatis?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true&allowPublicKeyRetrieval=true
spring.datasource.default.username=root
spring.datasource.default.password=rootspring.datasource.slave.driverClassName=com.mysql.cj.jdbc.Driver
spring.datasource.slave.jdbcUrl=jdbc:mysql://xxxxxx/mybatis?useUnicode=true&characterEncoding=UTF-8&useSSL=false
spring.datasource.slave.username=root
spring.datasource.slave.password=rootmapper.identity=MYSQL
mapper.wrap-keyword= `{0}`
mybatis.type-aliases-package=com.example.simplejobdemo.entity
mybatis.mapper-locations=classpath:mapper/*.xml
##mybatis.mapper-locations=classpath:mapper/base/**/*.xml,mapper/common/**/*.xml,mapper/core/**/*.xml,workflow/*.xml,com/sitech/pgcenter/mapper/core/*.xml,base/**/*.xmlmybatis.configuration.map-underscore-to-camel-case=true
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
mybatis.configuration.jdbc-type-for-null=null

创建数据源,对于动态数据源一定要加上 @Primary注解。 

@Configuration
public class DataSourceConfig {@Bean@ConfigurationProperties(prefix = "spring.datasource.default")public DataSource dataSourceDefault() {return DataSourceBuilder.create().build();}@Bean@ConfigurationProperties(prefix = "spring.datasource.slave")public DataSource dataSourceSlave() {return DataSourceBuilder.create().build();}/*** 动态数据源* @param dataSourceDefault 默认数据源* @param dataSourceSlave 从数据源* @return*/@Bean@Primarypublic DataSource dataSource(DataSource dataSourceDefault,DataSource dataSourceSlave) {Map<Object, Object> targetDataSources = new HashMap<>();targetDataSources.put(DataSourceKeyEnum.DEFAULT, dataSourceDefault);targetDataSources.put(DataSourceKeyEnum.SLAVE, dataSourceSlave);DynamicDataSource dataSource = new DynamicDataSource();dataSource.setTargetDataSources(targetDataSources);dataSource.setDefaultTargetDataSource(dataSourceSlave);return dataSource;}}

DataSourceAspect切面类

@Aspect
@Component
public class DataSourceAspect {//切点@Pointcut("@annotation(com.example.simplejobdemo.config.datasourceconf.DataSourceAnnotation)")public void pointCut() {}@Around(value = "pointCut()")public Object around(ProceedingJoinPoint joinPoint) throws Throwable {MethodSignature signature = (MethodSignature) joinPoint.getSignature();Method method = signature.getMethod();DataSourceAnnotation dataSourceAnnotation = method.getAnnotation(DataSourceAnnotation.class);DataSourceKeyEnum dataSourceKeyEnum = dataSourceAnnotation.value();if(dataSourceKeyEnum == null) {dataSourceKeyEnum = DataSourceKeyEnum.DEFAULT;}DynamicDataSource.DynamicDataSourceContextHolder.setDataSourceType(dataSourceKeyEnum);try {return joinPoint.proceed();}finally {DynamicDataSource.DynamicDataSourceContextHolder.clearDataSourceType();}}}

二:原理

AbstractRoutingDataSource类如何影响正在执行mybatis执行sql语句的数据源选择?

每个sql执行时,调用DataSource接口的getConnection()方法获取数据库的连接,实际执行是会使用AbstractRoutingDataSource类的getConnection()选取指定数据的连接(AbstractRoutingDataSource实现了DataSource接口),这就是项目中每个执行sql可以使用AbstractRoutingDataSource类中指定数据源的原因。

 这里getConnection方法调用时的核心方法determineTargetDataSourc()

核心方法是determineCurrentLookupKey(),通过这个方法调用获取业务指定的的map中key值,获取resolvedDataSources中指定key的数据源 。

determineCurrentLookupKey()的实现在自定义的子类方法中,自定义的子类方法中,将key值业务定义使用的是本地线程栈技术

运用本地线程栈,可以在线程中手动或者自动(拦截器)将key值设定到本地线程栈对象contextHolder中,当sql执行时会,对调用AbstractRoutingDataSource的getConnection(),再调用determineTargetDataSource(),子类中determineCurrentLookupKey()最终决定了从本地线程栈对象contextHolder获取当前数据源

如何初始化所有数据源?

继续看AbstractRoutingDataSource类的核心方法determineTargetDataSourc()

AbstractRoutingDataSource类本身有个四个核心属性:

//用来通过配置文件指定所有的key值和value数据源
private Map<Object, Object> targetDataSources;
//用来通过配置文件指定默认数据源
private Object defaultTargetDataSource;
//在afterPropertiesSet方法将defaultTargetDataSource中转为resolvedDefaultDataSource,这个是后面存储默认数据源
private DataSource resolvedDefaultDataSource;
//在afterPropertiesSet方法将targetDataSources中转为resolvedDataSources,这个是后面存储使用的名称-数据源映射
private Map<Object, DataSource> resolvedDataSources;

 其中resolvedDataSources又是如何初始化的?

AbstractRoutingDataSource类实现了InitializingBean接口,所以此方法在这个bean初始化时执行afterPropertiesSet方法。afterPropertiesSet方法将配置文件中注入的targetDataSources和defaultTargetDataSource 转换为了后续可以使用的resolvedDefaultDataSource(默认数据源)和resolvedDataSources(存储使用的名称-数据源映射)

而targetDataSources的初始化,就是我们通过配置实现的

http://www.yayakq.cn/news/677313/

相关文章:

  • 网站页面统计代码怎样做instergram网站营销
  • 怎样做自己网站后台不被攻击个人主页网站
  • 云浮新兴县做网站漯河住房建设局网站
  • 建设银行网站下载中心大连建设工程信息网防水
  • 网站建设合同免费下载网站建设 交易保障
  • 网站建设给客户看的ppt佛山做网站建设价格
  • 杭州网站建设公司代理加盟做网站ps图片都是多大
  • 51做网站wordpress左右滑动相册
  • 网站被降权后怎么办一个小程序制作价格
  • 网站开发毕业设计开题报告厚街做网站的公司
  • 石家庄建设网站公司奢侈品
  • 全国二级建造师注册信息查询网站北京的招聘网站有哪些
  • 开发网站网页归档企业网站建设重要性
  • 资兴网站设计三网合一网站开发
  • 重庆巫山网站设计公司英文网站收录提交
  • 苏州网站建设智能 乐云践新做外贸网站需要什么条件
  • 网站备案信息查询申请表黔江网站制作
  • 网站后台怎么上传图片产品学前端好找工作吗
  • 做网站wamp和xamp伊春网络运营推广
  • 廊坊网站推广范湖网站建设团队
  • 做做网站2023网页设计表格模板源代码
  • 甘肃省建设厅执业资格注册中心网站网络搭建百度百科
  • 做网站优化期间能收到网站吗广东东莞营销
  • 亚马逊店铺网站建设费用设计邦中国官网
  • 教育培训网站案例梭子手做鱼网站
  • 做金融量化的网站建设工程挂网是在那个网站
  • 学校网站建设的技术方案网站信息备案查询系统
  • 淘宝客做网站自动更新网站建设开发服务费税率
  • 国外网站设计欣赏上海 网站备案代理
  • 个人博客网站模板wordpresswordpress 链接地址