• Spring+MyBatis多数据源配置实现


    在开发项目时,有多数据源的需求。在网上查阅资料后,实现了。由于本人经验不足,且需求本身要求不高,所以采用手动控制,非自动切换。

    概览

    img

    使用技术

    IOC容器:Spring

    Web框架:SpringMVC

    ORM框架:Mybatis

    文件

    注意,以下改动是基于单数据源实现成功后。

    1. Spring 容器(XML)

      <?xml version="1.0" encoding="UTF-8"?>
      <beans xmlns="http://www.springframework.org/schema/beans"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xmlns:context="http://www.springframework.org/schema/context"
            xmlns:aop="http://www.springframework.org/schema/aop"
            xmlns:tx="http://www.springframework.org/schema/tx"
            xsi:schemaLocation="http://www.springframework.org/schema/beans
      http://www.springframework.org/schema/beans/spring-beans.xsd
      http://www.springframework.org/schema/context
      http://www.springframework.org/schema/context/spring-context.xsd
      http://www.springframework.org/schema/aop
      http://www.springframework.org/schema/aop/spring-aop.xsd
      http://www.springframework.org/schema/tx
      http://www.springframework.org/schema/tx/spring-tx.xsd">
      
         <!--加载数据库配置文件-->
         <context:property-placeholder location="classpath:jdbc.properties"/>
      
         <!-- ===============第一个数据源MySQL的配置=============== -->
         <!--配置数据源 c3p0 连接池-->
         <bean id="dataSource2MySQL" class="com.mchange.v2.c3p0.ComboPooledDataSource" >
             <property name="driverClass" value="${jdbc.mysql.driver}"/>
             <property name="jdbcUrl" value="${jdbc.mysql.url}"/>
             <property name="user" value="${jdbc.mysql.username}"/>
             <property name="password" value="${jdbc.mysql.password}"/>
             <!--以下皆为连接池参数,依实际情况配置-->
             <property name="maxPoolSize" value="200"/>
             <property name="minPoolSize" value="10"/>
             <!--初始化时获取的连接数,取值应在minPoolSize与maxPoolSize之间。Default: 3 -->
             <property name="initialPoolSize" value="10"/>
             <property name="checkoutTimeout" value="60"/>
             <property name="unreturnedConnectionTimeout" value="25"/>
             <property name="maxIdleTimeExcessConnections" value="20"/>
             <property name="maxConnectionAge" value="20"/>
             <property name="idleConnectionTestPeriod" value="50"/>
             <property name="maxStatements" value="0"/>
      
         </bean>
      
         <!-- ===============第二个数据源SQLServer的配置=============== -->
      
         <!--配置数据源 c3p0 连接池-->
         <bean id="dataSource2SQLServer" class="com.mchange.v2.c3p0.ComboPooledDataSource" >
             <property name="driverClass" value="${jdbc.sqlserver.driver}"/>
             <property name="jdbcUrl" value="${jdbc.sqlserver.url}"/>
             <property name="user" value="${jdbc.sqlserver.username}"/>
             <property name="password" value="${jdbc.sqlserver.password}"/>
             <!--以下皆为连接池参数,依实际情况配置-->
             <property name="maxPoolSize" value="200"/>
             <!--初始化时获取的连接数,取值应在minPoolSize与maxPoolSize之间。Default: 3 -->
             <property name="initialPoolSize" value="10"/>
             <property name="minPoolSize" value="10"/>
             <property name="checkoutTimeout" value="60"/>
             <property name="unreturnedConnectionTimeout" value="25"/>
             <property name="maxIdleTimeExcessConnections" value="20"/>
             <property name="maxConnectionAge" value="20"/>
             <property name="idleConnectionTestPeriod" value="50"/>
             <property name="maxStatements" value="0"/>
         </bean>
      
         <!--将DynamicDataSource Bean加入到Spring的上下文xml配置文件中去,同时配置DynamicDataSource的targetDataSources(多数据源目标)属性的Map映射。-->
      
         <bean id="dataSource" class="com.system.util.DynamicDataSource">
             <property name="targetDataSources">
                 <map key-type="java.lang.String">
                     <entry key="dataSource2MySQL" value-ref="dataSource2MySQL"/>
                     <entry key="dataSource2SQLServer"  value-ref="dataSource2SQLServer" />
                 </map>
             </property>
             <property name="defaultTargetDataSource" ref="dataSource2MySQL"/>
         </bean>
      
         <!--配置SqlSessionFactory-->
         <bean id="sessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
             <!--加载mybatis配置文件-->
             <property name="configLocation" value="classpath:mybatis/mybatis.cfg.xml"/>
             <!--数据源-->
             <property name="dataSource" ref="dataSource"/>
         </bean>
      
         <!--Mapper批量扫描,从Mapper包扫描接口,自动创建代理对象,并在Spring容器中自动注册
         使用 Mybatis与Spring整合包的这个 Mapper 扫描器后, Mybatis 配置文件里的扫描器,就可以取消掉了
         遵循的规范 不变
         自动扫描出来的Mapper的bean的id为Mapper类名(首字母小写)
         -->
         <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
             <!--如果需要扫描多个报下的mapper,每个包中间使用半角逗号分开-->
             <property name="basePackage" value="com.system.mapper"/>
             <property name="sqlSessionFactoryBeanName" value="sessionFactory"/>
         </bean>
      </beans>

      在 Spring 容器中配置两个数据源。

    2. CustomerContextHolder

      public class CustomerContextHolder {
         //MySQL
         public static final String DATA_SOURCE_MYSQL = "dataSource2MySQL";
         //SQLServer
         public static final String DATA_SOURCE_MSSQL = "dataSource2SQLServer";
         //用ThreadLocal来设置当前线程使用哪个dataSource
         private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();
         public static void setCustomerType(String customerType) {
             contextHolder.set(customerType);
         }
         public static String getCustomerType() {
             String dataSource = contextHolder.get();
             if (StringUtils.isEmpty(dataSource)) {
                 return DATA_SOURCE_MYSQL;
             }else {
                 return dataSource;
             }
         }
         public static void clearCustomerType() {
             contextHolder.remove();
         }
      }

      获得和设置上下文环境,为一线程安全的 ThreadLocal 。

    3. DynamicDataSource

      public class DynamicDataSource extends AbstractRoutingDataSource {
         @Override
         protected Object determineCurrentLookupKey() {
             return CustomerContextHolder.getCustomerType();
         }
      }

      DynamicDataSource 动态数据源类,扩展 Spring 的 AbstractRoutingDataSource 抽象类,实现动态数据源, AbstractRoutingDataSource 中的抽象方法 determineCurrentLookupKey 是实现数据源的 route 的核心.这里对该方法进行 Override 。

    使用

       //切换数据源至SQLServer
       CustomerContextHolder.setCustomerType(CustomerContextHolder.DATA_SOURCE_MSSQL);
       //切换数据源至MySQL
       CustomerContextHolder.setCustomerType(CustomerContextHolder.DATA_SOURCE_MYSQL);
  • 相关阅读:
    装饰器模块和面试题
    装饰器和推导式
    设计商城系统,主要提供两个功能:商品管理、会员管理。
    写代码:三级菜单
    写代码:循环打印names列表,把元素和索引值都打印出来。
    写代码: 编写登录接口
    写代码:假设一年期定期利率为3.25%,计算一下需要过多少年,一万元的一年定期存款连本带息能翻番?
    写代码:输入一年份,判断该年份是否是闰年并输出结果。
    写代码:制作趣味模板程序
    变量n1和n2是什么关系
  • 原文地址:https://www.cnblogs.com/Sherlock-J/p/12925979.html
Copyright © 2020-2023  润新知