• spring+mybatis+多数据源(mysql+oracle)配置


    1.自定义注解

    1. @Target({ElementType.TYPE,ElementType.METHOD})
    2. @Retention(RetentionPolicy.RUNTIME)
    3. public @interface DataSource {
    4. String value();
    5. }

    2.

    1. package com.utils;
    2. public class DbContextHolder {
    3. private static final ThreadLocal<String>THREAD_DATA_SOURCE =new ThreadLocal<>();
    4. /**
    5. * 设置当前数据库
    6. */
    7. public static void setDataSource(String dataSource) {
    8. THREAD_DATA_SOURCE.set(dataSource);
    9. }
    10. /**
    11. * 取得当前数据库
    12. */
    13. public static String getDataSource() {
    14. return THREAD_DATA_SOURCE.get();
    15. }
    16. /**
    17. * 清除上下文数据
    18. */
    19. public static void clearDataSource() {
    20. THREAD_DATA_SOURCE.remove();
    21. }
    22. }

    3.

    1. package com.utils;
    2. import java.lang.reflect.Method;
    3. import org.aspectj.lang.JoinPoint;
    4. import org.aspectj.lang.reflect.MethodSignature;
    5. public class DataSourceAspect {
    6. // 拦截目标方法,获取由@DataSource指定的数据源标识,设置到线程存储中以便切换数据源
    7. public void intercept(JoinPoint point) throws Exception{
    8. Class<?> target = point.getTarget().getClass();
    9. MethodSignature signature=(MethodSignature)point.getSignature();
    10. // 默认使用目标类型的注解,如果没有则使用其实现接口的注解
    11. for (Class<?> clazz : target.getInterfaces()) {
    12. resolveDataSource(clazz, signature.getMethod());
    13. }
    14. resolveDataSource(target, signature.getMethod());
    15. }
    16. /**
    17. * 提取目标对象方法注解和类型注解中的数据源标识
    18. */
    19. public void resolveDataSource(Class<?>clazz,Method method) {
    20. try {
    21. Class<?>[]types=method.getParameterTypes();
    22. // 默认使用类型注解
    23. if (clazz.isAnnotationPresent(DataSource.class)) {
    24. DataSource source = clazz.getAnnotation(DataSource.class);
    25. DbContextHolder.setDataSource(source.value());
    26. }
    27. // 方法注解可以覆盖类型注解
    28. Method m=clazz.getMethod(method.getName(), types);
    29. if (m!=null && m.isAnnotationPresent(DataSource.class)) {
    30. DataSource source = m.getAnnotation(DataSource.class);
    31. DbContextHolder.setDataSource(source.value());
    32. }
    33. } catch (Exception e) {
    34. System.out.println(clazz+":"+e.getMessage());
    35. }
    36. }
    37. }

    4.

    1. package com.utils;
    2. import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
    3. public class MultipleDataSource extends AbstractRoutingDataSource {
    4. @Override
    5. protected Object determineCurrentLookupKey() {
    6. // TODO Auto-generated method stub
    7. return DbContextHolder.getDataSource();
    8. }
    9. }

    1. <!-- 将多个配置文件读取到容器中,交给Spring管理 -->
    2. <bean id="propertyConfigurer"
    3. class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    4. <property name="locations">
    5. <list>
    6. <!-- 这里支持多种寻址方式:classpath和file -->
    7. <value>classpath:db.properties</value>
    8. </list>
    9. </property>
    10. </bean>
    11. <bean id="dataSource_mysql" class="com.zaxxer.hikari.HikariDataSource" destroy-method="close">
    12. <property name="username" value="${user}"/>
    13. <property name="password" value="${password}"/>
    14. <property name="driverClassName" value="${driverClassName}"/>
    15. <property name="jdbcUrl" value="${jdbcUrl}"/>
    16. <!--<property name="jdbcUrl" value="jdbc:mysql://47.96.75.158:3306/a?characterEncoding=UTF-8"/>-->
    17. </bean>
    18. <bean id="dataSource_oracle" class="com.zaxxer.hikari.HikariDataSource" destroy-method="close">
    19. <property name="driverClassName" value="${jdbc.dataSourceDriver}" />
    20. <property name="jdbcUrl" value="${jdbc.dataSourceUrl}" />
    21. <property name="username" value="${jdbc.dataSourceUser}" />
    22. <property name="password" value="${jdbc.dataSourcePasswd}" />
    23. </bean>
    24. <!-- 下面的是切换数据库的自定义类 -->
    25. <bean id="dataSource" class="com.utils.MultipleDataSource">
    26. <!-- 默认使用mysql数据库 -->
    27. <property name="defaultTargetDataSource" ref="dataSource_mysql"></property>
    28. <property name="targetDataSources">
    29. <map>
    30. <entry key="dataSource_mysql" value-ref="dataSource_mysql"></entry>
    31. <entry key="dataSource_oracle" value-ref="dataSource_oracle"></entry>
    32. </map>
    33. </property>
    34. </bean>
    35. <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    36. <property name="dataSource" ref="dataSource" />
    37. <property name="mapperLocations" value="classpath:mapper/*.xml" />
    38. <!--注意其他配置-->
    39. <property name="plugins">
    40. <array>
    41. <bean class="com.github.pagehelper.PageInterceptor">
    42. <property name="properties">
    43. <!--使用下面的方式配置参数,一行配置一个 -->
    44. <value>
    45. rowBoundsWithCount=true
    46. PageRowBounds=true
    47. offsetAsPageNum=true
    48. pageSizeZero=true
    49. reasonable=true
    50. </value>
    51. </property>
    52. </bean>
    53. </array>
    54. </property>
    55. <property name="configLocation" value="classpath:mybatis_configer.xml"></property><!-- 配置mybatis的日志记录 -->
    56. </bean>
    57. <!--扫描依赖注入关联接口-->
    58. <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    59. <property name="basePackage" value="com.dao"/>
    60. <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
    61. </bean>
    62. <!-- ================================事务相关控制================================================= -->
    63. <bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    64. <property name="dataSource" ref="dataSource"></property>
    65. </bean>
    66. <tx:advice id="userTxAdvice" transaction-manager="transactionManager">
    67. <tx:attributes>
    68. <tx:method name="delete*" propagation="REQUIRED" read-only="false"
    69. rollback-for="java.lang.Exception" no-rollback-for="java.lang.RuntimeException"/>
    70. <tx:method name="insert*" propagation="REQUIRED" read-only="false"
    71. rollback-for="java.lang.RuntimeException" />
    72. <tx:method name="update*" propagation="REQUIRED" read-only="false"
    73. rollback-for="java.lang.Exception" />
    74. <tx:method name="find*" propagation="SUPPORTS"/>
    75. <tx:method name="get*" propagation="SUPPORTS"/>
    76. <tx:method name="select*" propagation="SUPPORTS"/>
    77. </tx:attributes>
    78. </tx:advice>
    79. <!-- 切面 -->
    80. <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
    81. <bean id="dataSourceAspect" class="com.utils.DataSourceAspect"></bean>
    82. <!--@Transactional(rollbackFor = Exception.class)使用下面的aop就不用每个类,或者方法使用注解了-->
    83. <aop:config>
    84. <aop:pointcut expression="execution(public * com.service.*.*(..))" id="pc"/>
    85. <!-- <aop:pointcut id="pc" expression="execution(public * com.dao.*.*(..))" /> &lt;!&ndash;把事务控制在Dao层&ndash;&gt;-->
    86. <aop:advisor pointcut-ref="pc" advice-ref="userTxAdvice" />
    87. <aop:aspect ref="dataSourceAspect">
    88. <!-- 拦截所有service方法,在dao层添加注解 -->
    89. <aop:pointcut expression="execution(* com.dao..*.*(..))" id="dataSourcePointcut"/>
    90. <aop:before method="intercept" pointcut-ref="dataSourcePointcut"/>
    91. </aop:aspect>
    92. </aop:config>

    测试执行效果:

    ----------------------mysql---------------------------
    2020-06-22 11:05:15 [http-nio-8080-exec-4] DEBUG SqlSessionUtils:97 - Creating a new SqlSession
    2020-06-22 11:05:15 [http-nio-8080-exec-4] DEBUG SqlSessionUtils:148 - SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@4a9c057] was not registered for synchronization because synchronization is not active
    2020-06-22 11:05:15 [http-nio-8080-exec-4] DEBUG DataSourceUtils:114 - Fetching JDBC Connection from DataSource
    2020-06-22 11:05:18 [http-nio-8080-exec-4] DEBUG SpringManagedTransaction:87 - JDBC Connection [HikariProxyConnection@987002885 wrapping com.mysql.jdbc.JDBC4Connection@627776c6] will not be managed by Spring
    2020-06-22 11:05:18 [http-nio-8080-exec-4] DEBUG getAll:145 - ==>  Preparing: select * from user
    2020-06-22 11:05:18 [http-nio-8080-exec-4] DEBUG getAll:145 - ==> Parameters:
    2020-06-22 11:05:18 [http-nio-8080-exec-4] DEBUG getAll:145 - <==      Total: 12
    2020-06-22 11:05:18 [http-nio-8080-exec-4] DEBUG SqlSessionUtils:191 - Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@4a9c057]
    2020-06-22 11:05:18 [http-nio-8080-exec-4] DEBUG DataSourceUtils:340 - Returning JDBC Connection to DataSource
    User{id=1, username='小一', password='1234', idCardNo='null', birthday='null', phone='null', email='null', sex='null', age=null, createTime=null, updateTime=null, provinceCode='null', cityCode='null', districtCode='null', address='null', detailAddress='null', desp='null', type=null, orForbidden=null, orDel=null}
    User{id=2, username='小二', password='1234', idCardNo='null', birthday='null', phone='null', email='null', sex='null', age=null, createTime=null, updateTime=null, provinceCode='null', cityCode='null', districtCode='null', address='null', detailAddress='null', desp='null', type=null, orForbidden=null, orDel=null}
    User{id=3, username='小三', password='1234', idCardNo='null', birthday='null', phone='null', email='null', sex='null', age=null, createTime=null, updateTime=null, provinceCode='null', cityCode='null', districtCode='null', address='null', detailAddress='null', desp='null', type=null, orForbidden=null, orDel=null}
    User{id=4, username='小四', password='1234', idCardNo='null', birthday='null', phone='null', email='null', sex='null', age=null, createTime=null, updateTime=null, provinceCode='null', cityCode='null', districtCode='null', address='null', detailAddress='null', desp='null', type=null, orForbidden=null, orDel=null}
    User{id=5, username='小五', password='1234', idCardNo='null', birthday='null', phone='null', email='null', sex='null', age=null, createTime=null, updateTime=null, provinceCode='null', cityCode='null', districtCode='null', address='null', detailAddress='null', desp='null', type=null, orForbidden=null, orDel=null}
    User{id=6, username='小六', password='1234', idCardNo='null', birthday='null', phone='null', email='null', sex='null', age=null, createTime=null, updateTime=null, provinceCode='null', cityCode='null', districtCode='null', address='null', detailAddress='null', desp='null', type=null, orForbidden=null, orDel=null}
    User{id=7, username='小七', password='1234', idCardNo='null', birthday='null', phone='null', email='null', sex='null', age=null, createTime=null, updateTime=null, provinceCode='null', cityCode='null', districtCode='null', address='null', detailAddress='null', desp='null', type=null, orForbidden=null, orDel=null}
    User{id=8, username='小八', password='1234', idCardNo='null', birthday='null', phone='null', email='null', sex='null', age=null, createTime=null, updateTime=null, provinceCode='null', cityCode='null', districtCode='null', address='null', detailAddress='null', desp='null', type=null, orForbidden=null, orDel=null}
    User{id=9, username='小九', password='1234', idCardNo='null', birthday='null', phone='null', email='null', sex='null', age=null, createTime=null, updateTime=null, provinceCode='null', cityCode='null', districtCode='null', address='null', detailAddress='null', desp='null', type=null, orForbidden=null, orDel=null}
    User{id=10, username='小十', password='1234', idCardNo='null', birthday='null', phone='null', email='null', sex='null', age=null, createTime=null, updateTime=null, provinceCode='null', cityCode='null', districtCode='null', address='null', detailAddress='null', desp='null', type=null, orForbidden=null, orDel=null}
    User{id=11, username='小去fadsf', password='1234', idCardNo='null', birthday='null', phone='null', email='null', sex='男', age=null, createTime=null, updateTime=null, provinceCode='null', cityCode='null', districtCode='null', address='null', detailAddress='null', desp='null', type=null, orForbidden=null, orDel=null}
    User{id=12, username='小去fadsf', password='1234', idCardNo='null', birthday='null', phone='null', email='null', sex='男', age=null, createTime=null, updateTime=null, provinceCode='null', cityCode='null', districtCode='null', address='null', detailAddress='null', desp='null', type=null, orForbidden=null, orDel=null}
    ----------------------oralce---------------------------
    2020-06-22 11:05:18 [http-nio-8080-exec-4] DEBUG SqlSessionUtils:97 - Creating a new SqlSession
    2020-06-22 11:05:18 [http-nio-8080-exec-4] DEBUG SqlSessionUtils:148 - SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@38c5c7c9] was not registered for synchronization because synchronization is not active
    2020-06-22 11:05:18 [http-nio-8080-exec-4] DEBUG DataSourceUtils:114 - Fetching JDBC Connection from DataSource
    2020-06-22 11:05:19 [http-nio-8080-exec-4] DEBUG SpringManagedTransaction:87 - JDBC Connection [HikariProxyConnection@24572899 wrapping oracle.jdbc.driver.T4CConnection@79232d37] will not be managed by Spring
    2020-06-22 11:05:19 [http-nio-8080-exec-4] DEBUG getAll:145 - ==>  Preparing: select * from "sys_user"
    2020-06-22 11:05:20 [http-nio-8080-exec-4] DEBUG getAll:145 - ==> Parameters:
    2020-06-22 11:05:20 [http-nio-8080-exec-4] DEBUG getAll:145 - <==      Total: 5
    2020-06-22 11:05:20 [http-nio-8080-exec-4] DEBUG SqlSessionUtils:191 - Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@38c5c7c9]
    2020-06-22 11:05:20 [http-nio-8080-exec-4] DEBUG DataSourceUtils:340 - Returning JDBC Connection to DataSource
    {birthday=2020-10-26, password=1234, createtime=2020-06-08 08:59:22.0, address=地址, phone=15255710558, userane=小一, sex=女, id=1}
    {birthday=2020-10-26, password=1234, createtime=2020-06-08 08:59:22.0, address=地址, phone=15255710558, userane=小二, sex=女, id=2}
    {birthday=2020-10-26, password=1234, createtime=2020-06-08 08:59:22.0, address=地址, phone=15255710558, userane=小三, sex=女, id=3}
    {birthday=2020-10-26, password=1234, createtime=2020-06-08 08:59:22.0, address=地址, phone=15255710558, userane=小四, sex=女, id=4}
    {birthday=2020-10-26, password=1234, createtime=2020-06-08 08:59:22.0, address=地址, phone=15255710558, userane=小五, sex=女, id=5}
    2020-06-22 11:05:20 [http-nio-8080-exec-4] DEBUG RequestResponseBodyMethodProcessor:267 - Using 'application/json;q=0.8', given [text/html, application/xhtml+xml, image/webp, image/apng, application/signed-exchange;v=b3, application/xml;q=0.9, */*;q=0.8] and supported [application/json, application/*+json]
    2020-06-22 11:05:20 [http-nio-8080-exec-4] DEBUG RequestResponseBodyMethodProcessor:297 - Nothing to write: null body
    2020-06-22 11:05:20 [http-nio-8080-exec-4] DEBUG DispatcherServlet:1123 - Completed 200 OK

  • 相关阅读:
    王道数据结构——树
    冲刺学习-MySQL-基础
    AQS 组件
    开源与闭源:AI模型发展的两条路径
    MySql学习之慢SQL优化和慢SQL案例
    uni-app —— 下拉刷新 & 上拉加载
    Docker配置nginx
    【IDEA配置】IDEA配置
    【网站项目】学习资料销售平台 小程序
    【力扣每日一题】2023.9.15 宝石补给
  • 原文地址:https://blog.csdn.net/qq_38310446/article/details/106897888