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

ssm 多数据源 注解版本

application.xml 配置如下

<!-- 使用 DruidDataSource 数据源 --><bean id="primaryDataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"></bean>
<!-- 使用 数据源 1--><bean id="logDataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"></bean><!-- 配置动态加载数据源 --><bean id="druidDynamicDataSource" class="com.iss.sso.utils.DynamicDataSource"><property name="defaultTargetDataSource" ref="primaryDataSource" /><property name="targetDataSources"><map><entry key="primaryDataSource" value-ref="primaryDataSource"/><entry key="scheduleDataSource" value-ref="logDataSource"/></map></property></bean>
<!--3.配置SqlSessionFactory对象--><bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"><!--往下才是mybatis和spring真正整合的配置--><!--注入数据库连接池--><property name="dataSource" ref="druidDynamicDataSource"/><!--配置mybatis全局配置文件:mybatis-config.xml指定Mybatis的配置文件位置。如果指定了该属性,那么会以该配置文件的内容作为配置信息构建对应的SqlSessionFactoryBuilder,但是后续属性指定的内容会覆盖该配置文件里面指定的对应内容--><property name="configLocation" value="classpath:mybatis-config.xml"/><!--扫描entity包,使用别名,多个用;隔开一般对应实体类所在的包,这个时候会自动取对应包中不包括包名的简单类名作为包括包名的别名。多个package之间可以用逗号或者分号等来进行分隔。(value的值一定要是包的全名)--><property name="typeAliasesPackage" value="com.sso.**.domain"/><!--扫描sql配置文件:mapper需要的xml文件Mapper文件存放的位置,当Mapper文件跟对应的Mapper接口处于同一位置的时候可以不用指定该属性的值--><property name="mapperLocations" value="classpath:/mapper/*.xml"/></bean>
-----     动态数据源
<bean id="dynamicDataSourceAspect" class="com.sso.utils.DynamicDataSourceAspect"></bean><!--配置事务管理器--><bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><!--引入数据源--><property name="dataSource" ref="druidDynamicDataSource"/></bean><!-- 开启事务注解 --><tx:annotation-driven transaction-manager="transactionManager"/><!--定义事务增强,并制定事务管理器  --><tx:advice id="txAdvice" transaction-manager="transactionManager"><tx:attributes><!--设置传播行为--><tx:method name="save*" propagation="REQUIRED" isolation="DEFAULT"/><tx:method name="update*" propagation="REQUIRED" isolation="DEFAULT"/><tx:method name="del*" propagation="REQUIRED" isolation="DEFAULT"/><tx:method name="select*" propagation="SUPPORTS" isolation="DEFAULT" read-only="true"/><tx:method name="*" propagation="REQUIRED" isolation="DEFAULT"/></tx:attributes></tx:advice><aop:config proxy-target-class="true"><aop:pointcut id="myPointcut" expression="execution(* com.sso.*.dao.*.*(..))"/><aop:advisor advice-ref="dynamicDataSourceAspect" pointcut-ref="myPointcut" order="1"/><!--把事务控制在Service层--><aop:advisor advice-ref="txAdvice" pointcut-ref="myPointcut" order="2"/></aop:config>

动态数据源 核心类

/*** 动态数据源加载** @author*/
public class DynamicDataSource extends AbstractRoutingDataSource {private static final Logger logger = LoggerFactory.getLogger(DynamicDataSource.class);/*** 数据源标识,保存在线程变量中,避免多线程操作数据源时互相干扰*/private static final ThreadLocal<String> key = new ThreadLocal<String>();@Overrideprotected Object determineCurrentLookupKey() {logger.debug("===当前数据源: {}===", key.get());return key.get();}/*** 设置数据源** @param dataSource 数据源名称*/public static void setDataSource(String dataSource) {key.set(dataSource);}/*** 获取数据源** @return*/public static String getDatasource() {return key.get();}/*** 清除数据源*/public static void clearDataSource() {key.remove();}}

spring aop 植入

@Aspect
@Order(-10)
@Component
public class DynamicDataSourceAspect implements MethodBeforeAdvice, AfterReturningAdvice {Logger log = LoggerFactory.getLogger("切换数据源");/*** 目标方法正常完成后被织入,关闭数据源** @param o* @param method* @param objects* @param o1* @throws Throwable*/@Overridepublic void afterReturning(Object o, Method method, Object[] objects, Object o1) {//这里做一个判断,有使用DataSourceAnnotation注解时才关闭数据源,有一个主要的数据源,就没有必要每次都去关闭if (method.isAnnotationPresent(DataSourceAnnotation.class)) {DynamicDataSource.clearDataSource();log.debug("数据源已关闭");}}/*** 拦截目标方法,获取由@DataSourceAnnotation指定的数据源标识,设置到线程存储中以便切换数据源*/@Overridepublic void before(Method method, Object[] objects, Object o) throws Throwable {if (method.isAnnotationPresent(DataSourceAnnotation.class)) {String clazzName = method.getDeclaringClass().getName();String methodName = method.getName();log.info("{}.{} 准备切换数据源", clazzName, methodName, DynamicDataSource.getDatasource());DataSourceAnnotation dataSourceAnnotation = method.getAnnotation(DataSourceAnnotation.class);DynamicDataSource.setDataSource(dataSourceAnnotation.value());log.info("{}.{} 数据源切换为:{}", clazzName, methodName, DynamicDataSource.getDatasource());} else {DynamicDataSource.setDataSource(DataSourceAnnotation.PRIMARY);}}
}

http://www.lryc.cn/news/499289.html

相关文章:

  • selenium常见接口函数使用
  • STM32F103单片机使用STM32CubeMX新建IAR工程步骤
  • 刷题重开:找出字符串中第一个匹配项的下标——解题思路记录
  • product/admin/list?page=0size=10field=jancodevalue=4562249292272
  • 人工智能机器学习无监督学习概念及应用详解
  • APM装机教程(五):测绘无人船
  • 微信小程序 运行出错 弹出提示框(获取token失败,请重试 或者 请求失败)
  • IDEA的service窗口中启动类是灰色且容易消失
  • R中利用ggplot2绘制气泡图
  • CID引流电商
  • 在google cloud虚拟机上配置anaconda虚拟环境简单教程
  • windows下用vs搭配clang一起生成抽象语法树
  • 输入法:点三下输入一个汉字
  • URL访问网址的全过程
  • Thonny IDE + MicroPython + ESP32 + GY-302 测量环境中的光照强度
  • 小程序-基于java+SpringBoot+Vue的智慧校园管理系统设计与实现
  • 基于Java+Swing+Mysql的网络聊天室
  • javascript 的map()和join()
  • 深入理解 PyTorch 自动微分机制与自定义 torch.autograd.Function
  • 《C++ 赋能 K-Means 聚类算法:开启智能数据分类之旅》
  • 对 JavaScript 说“不”
  • spring下的beanutils.copyProperties实现深拷贝
  • 蓝桥杯二分题
  • 3D数字化革新,探索博物馆的正确打开新方式!
  • 工业检测基础-工业相机选型及应用场景
  • 通过 FRP 实现 P2P 通信:控制端与被控制端配置指南
  • 即时通信系统项目总览
  • QT获取tableview选中的行和列的值
  • GDPU 人工智能 期末复习
  • 编程之路,从0开始:补充篇