导读-
      在项目中可能有时候我们需要配置多套数据源,网上巴拉巴拉半天,都讲得太潦草了,对于第一次搞的人来说确实有点头疼,与其说在网上瞎找,还不如认真的自己动手操练一波,下面我就来介绍一下mybatis实现多套数据源的方式。
      刚开始我也是和大家一样,利用mybatis的mybatis-generator-core-1.3.2从表生成xml文件,这里写个小插曲,照顾一下新手,(老司机可以绕道,可以跳过阅读),可以按照下面的方式进行

  • 1:配置一下配置文件
    一般主要是配置一下数据库连接,和需要生成的表,以及导出的位置,详细内容下下面配置
<?xml version="1.0" encoding="UTF-8"?>  <!DOCTYPE generatorConfiguration    PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"    "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">  <generatorConfiguration>  <!-- 数据库驱动-->      <classPathEntry  location="mysql-connector-java-5.1.25-bin.jar"/>      <context id="DB2Tables"  targetRuntime="MyBatis3">          <commentGenerator>              <property name="suppressDate" value="true"/>              <!-- 是否去除自动生成的注释 true:是 : false:否 -->              <property name="suppressAllComments" value="true"/>          </commentGenerator>        <!--数据库链接URL,用户名、密码 -->          <jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://127.0.0.1/test" userId="root" password="123456">          </jdbcConnection>          <javaTypeResolver>              <property name="forceBigDecimals" value="false"/>          </javaTypeResolver>          <!-- 生成模型的包名和位置-->          <javaModelGenerator targetPackage="com.bufan.admin.commodity.entity" targetProject="src">              <property name="enableSubPackages" value="true"/>              <property name="trimStrings" value="true"/>          </javaModelGenerator>          <!-- 生成映射文件的包名和位置 G:\git\twjitm\src\main\resources\mapper-->          <sqlMapGenerator targetPackage="com.bufan.admin.commodity.dao" targetProject="src">              <property name="enableSubPackages" value="true"/>          </sqlMapGenerator>          <!-- 生成DAO的包名和位置-->          <javaClientGenerator type="XMLMAPPER" targetPackage="com.bufan.admin.commodity.dao" targetProject="src">              <property name="enableSubPackages" value="true"/>          </javaClientGenerator>          <!-- 要生成的表 tableName是数据库中的表名或视图名 domainObjectName是实体类名-->          <table tableName="tableName" domainObjectName="domainObjectName" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"></table>    </context>  </generatorConfiguration>  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 执行编译命令

通过完成配置文件的编写后,在mybatis-generator-core-1.3.2.jar同级目录,执行编译命令,就可以轻松完成又表生成实体类和xml的mapper文件啦。命令如下

java -jar mybatis-generator-core-1.3.2.jar -configfile generatorConfig.xml -overwrite
  • 1

注意:若是原来有对应的xml文件,新生成的文件会追加到原来的mapper文件后面,尼玛,我就被坑了一次,后来查看居然有相同的方法在xml文件里面,项目启动报错。 
相关包和文件请点击这里

言归正传
首先,我们在项目中创建一个jdbc.properties文件,可以将全部的数据库地址写入到此配置文件中

jdbc.driver=com.mysql.jdbc.Driver#服务器数据库#jdbc.url=jdbc:mysql://67.209.190.39:3306/twjitm?useUnicode=true&characterEncoding=utf-8#jdbc.username=root#jdbc.password=123456#本地数据库#jdbc.url=jdbc:mysql://127.0.0.1:3306/twjitm?useUnicode=true&characterEncoding=utf-8#本地服后台管理系统数据库地址jdbc.url-admin=jdbc:mysql://127.0.0.1:3306/admin?useUnicode=true&characterEncoding=utf-8jdbc.username-admin=rootjdbc.password-admin=123456#商城网站地址jdbc.url-shop=jdbc:mysql://127.0.0.1:3306/shop?useUnicode=true&characterEncoding=utf-8jdbc.username-shop=rootjdbc.password-shop=123456#正式服服务器地址#最大连接数c3p0.maxPoolSize=30000#最小连接数c3p0.minPoolSize=10#关闭连接后不自动commitc3p0.autoCommitOnClose=false#获取连接超时时间c3p0.checkoutTimeout=10000#当获取连接失败重试次数c3p0.acquireRetryAttempts=2
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

在进行配置
例如本例子中采用配置两套数据库来做测试,一个admin,一个shop两个数据源,在企业级开发中可能我们会对数据库采用很多分库分表策略,
其实原理都一样,
applicationContext.xml 中首先将properties文件加载进来,采用 context:property-placeholder 标签
可以同时加载多个这样的配置文件;下面就是我的项目中使用的,如有redis的配置文件,
applicationContext.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:mvc="http://www.springframework.org/schema/mvc"       xmlns:context="http://www.springframework.org/schema/context"       xsi:schemaLocation="http://www.springframework.org/schema/beans       http://www.springframework.org/schema/beans/spring-beans.xsd        http://www.springframework.org/schema/mvc        http://www.springframework.org/schema/mvc/spring-mvc.xsd       http://www.springframework.org/schema/context       http://www.springframework.org/schema/context/spring-context.xsd">    <mvc:annotation-driven/>    <!-- 切入点 -->    <context:property-placeholder            location="classpath:jdbc/jdbc.properties,classpath:redis/redis.properties"/>    <!--        <context:property-placeholder location="classpath:redis/redis.properties" ignore-unresolvable="true"/>    -->    <!--<bean class="com.twjitm.common.listener.StartupServerListener"></bean>--></beans>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

这样,我们就能够在xml文件中使用properties中定义的数据了,然而,我觉得上面介绍的内容可能大家都觉得太普遍了,其实都是为了使得mybatis配置多套数据源做准备工作,同时,我们在maven项目中集成这一个功能,在spring配置文件applicationContext-mybatis.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:tx="http://www.springframework.org/schema/tx"       xmlns:mvc="http://www.springframework.org/schema/mvc"       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/tx       http://www.springframework.org/schema/tx/spring-tx.xsd        http://www.springframework.org/schema/mvc        http://www.springframework.org/schema/mvc/spring-mvc.xsd">      <!-- 扫描service层 -->    <mvc:annotation-driven/>    <context:component-scan base-package="com.test.*.server" use-default-filters="false"/>    <!-- 数据库连接池 -->    <bean id="admin" class="com.mchange.v2.c3p0.ComboPooledDataSource">        <property name="driverClass" value="${jdbc.driver}"/>        <property name="jdbcUrl" value="${jdbc.url-admin}"/>        <property name="user" value="${jdbc.username-admin}"/>        <property name="password" value="${jdbc.password-admin}"/>        <property name="maxPoolSize" value="${c3p0.maxPoolSize}"/>        <property name="minPoolSize" value="${c3p0.minPoolSize}"/>        <property name="autoCommitOnClose" value="${c3p0.autoCommitOnClose}"/>        <property name="checkoutTimeout" value="${c3p0.checkoutTimeout}"/>        <property name="acquireRetryAttempts" value="${c3p0.acquireRetryAttempts}"/>    </bean>    <!--第二套数据源-->    <bean id="shop" class="com.mchange.v2.c3p0.ComboPooledDataSource">        <property name="driverClass" value="${jdbc.driver}"/>        <property name="jdbcUrl" value="${jdbc.url-shop}"/>        <property name="user" value="${jdbc.username-shop}"/>        <property name="password" value="${jdbc.password-shop}"/>        <property name="maxPoolSize" value="${c3p0.maxPoolSize}"/>        <property name="minPoolSize" value="${c3p0.minPoolSize}"/>        <property name="autoCommitOnClose" value="${c3p0.autoCommitOnClose}"/>        <property name="checkoutTimeout" value="${c3p0.checkoutTimeout}"/>        <property name="acquireRetryAttempts" value="${c3p0.acquireRetryAttempts}"/>    </bean>    <!--动态数据源的配置-->    <bean id="dynamicDataSource" class="com.test.common.mybatis.DynamicDataSource">        <property name="targetDataSources">            <map key-type="java.lang.String">                <entry value-ref="admin" key="admin"/>                <entry value-ref="shop" key="shop"/>            </map>        </property>        <property name="defaultTargetDataSource" ref="admin">        </property>    </bean>    <!-- 配置SqlSessionFactory对象 -->    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">        <!-- 注入数据库连接池 -->        <property name="dataSource" ref="dynamicDataSource"/>        <!-- 扫描model包 使用别名 -->        <property name="typeAliasesPackage" value="com.bufan.admin.*.entity"/>        <!-- 扫描sql配置文件:mapper需要的xml文件 -->        <!-- <property name="mapperLocations" value="classpath:mapper/*.xml"/>-->     <property name="mapperLocations" value="classpath:mapper/*/*.xml"/>        <property name="configurationProperties">            <props>                <prop key="mapUnderscoreToCamelCase">true</prop>            </props>        </property>        <!-- <property name="plugins" >             <array>                 <bean class="com.test.common.mybatis.mapperhelper.MapperInterceptor"/>             </array>         </property>-->    </bean>       <!--这个地方主要是用来用Mapper来替换xml文件形式的,与本例子无关-->   <!--<bean class="tk.mybatis.spring.mapper.MapperScannerConfigurer">        <property name="basePackage" value="com.bufan.admin.*.dao"/>        <property name="properties">            <value>                mappers=tk.mybatis.mapper.common.Mapper            </value>        </property>        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>    </bean>-->    <!-- 配置扫描Dao接口包,动态实现Dao接口,注入到spring容器中 -->   <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>       <property name="basePackage" value="com.test.admin.*.dao"/>    </bean>    <!-- 配置事务管理器 -->    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">        <!-- 注入数据库连接池 -->        <property name="dataSource" ref="dynamicDataSource"/>    </bean>    <!-- 配置基于注解的声明式事务 -->    <tx:annotation-driven transaction-manager="transactionManager"/></beans>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104

正如大家所看到的,添加了自定义一个类,一个是DynamicDataSource,其实DynamicDataSource,是继承了
spring的AbstractRoutingDataSource,充当了DataSource的路由中介, 能有在运行时, 根据某种key值来动态切换到真正的DataSource上。
在spring的官方文档上是这么介绍的
Abstract {@link javax.sql.DataSource} implementation that routes {@link #getConnection()}
calls to one of various target DataSources based on a lookup key. The latter is usually
(but not necessarily) determined through some thread-bound transaction context.
大概意思就是getConnection()根据查找lookup key键对不同目标数据源的调用,通常是通过(但不一定)某些线程绑定的事物上下文来实现。
 
通过这我们知道可以实现: 
      多数据源的动态切换,在程序运行时,把数据源数据源动态织入到程序中,灵活的进行数据源切换。 基于多数据源的动态切换,我们可以实现读写分离,这么做缺点也很明显,无法动态的增加数据源

DynamicDataSource.java 文件如下

public class DynamicDataSource extends AbstractRoutingDataSource {    @Override    protected Object determineCurrentLookupKey() {        System.out.println(CustomerContextHolder.getCustomerType());        return CustomerContextHolder.getCustomerType();    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

CustomerContextHolder.java文件内容输入,采用ThreadLocal模式来实现一个安全的线程访问,有关ThreadLocal类更多
内容,请点击这里

public class CustomerContextHolder {    public static final String DATASOURCE_ADMIN = "admin";    public static final String DATASOURCE_SHOP = "shop";    public static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();    public static void setCustomerType(String customerType) {        contextHolder.set(customerType);    }    public static String getCustomerType() {        return contextHolder.get();    }    public static void clearCustomerType() {        contextHolder.remove();    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

最后,比如要操作数据库的时候我们只需要在设置
  springMVC +mybatis+mysql多套数据源配置CustomerContextHolder.setCustomerType(CustomerContextHolder.DATASOURCE_SHOP);
就代表要操作shop这个库了。
 到此,我们就能实现mybatis动态的切换数据源。

           

再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow

                     

导读-
      在项目中可能有时候我们需要配置多套数据源,网上巴拉巴拉半天,都讲得太潦草了,对于第一次搞的人来说确实有点头疼,与其说在网上瞎找,还不如认真的自己动手操练一波,下面我就来介绍一下mybatis实现多套数据源的方式。
      刚开始我也是和大家一样,利用mybatis的mybatis-generator-core-1.3.2从表生成xml文件,这里写个小插曲,照顾一下新手,(老司机可以绕道,可以跳过阅读),可以按照下面的方式进行

  • 1:配置一下配置文件
    一般主要是配置一下数据库连接,和需要生成的表,以及导出的位置,详细内容下下面配置
<?xml version="1.0" encoding="UTF-8"?>  <!DOCTYPE generatorConfiguration    PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"    "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">  <generatorConfiguration>  <!-- 数据库驱动-->      <classPathEntry  location="mysql-connector-java-5.1.25-bin.jar"/>      <context id="DB2Tables"  targetRuntime="MyBatis3">          <commentGenerator>              <property name="suppressDate" value="true"/>              <!-- 是否去除自动生成的注释 true:是 : false:否 -->              <property name="suppressAllComments" value="true"/>          </commentGenerator>        <!--数据库链接URL,用户名、密码 -->          <jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://127.0.0.1/test" userId="root" password="123456">          </jdbcConnection>          <javaTypeResolver>              <property name="forceBigDecimals" value="false"/>          </javaTypeResolver>          <!-- 生成模型的包名和位置-->          <javaModelGenerator targetPackage="com.bufan.admin.commodity.entity" targetProject="src">              <property name="enableSubPackages" value="true"/>              <property name="trimStrings" value="true"/>          </javaModelGenerator>          <!-- 生成映射文件的包名和位置 G:\git\twjitm\src\main\resources\mapper-->          <sqlMapGenerator targetPackage="com.bufan.admin.commodity.dao" targetProject="src">              <property name="enableSubPackages" value="true"/>          </sqlMapGenerator>          <!-- 生成DAO的包名和位置-->          <javaClientGenerator type="XMLMAPPER" targetPackage="com.bufan.admin.commodity.dao" targetProject="src">              <property name="enableSubPackages" value="true"/>          </javaClientGenerator>          <!-- 要生成的表 tableName是数据库中的表名或视图名 domainObjectName是实体类名-->          <table tableName="tableName" domainObjectName="domainObjectName" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"></table>    </context>  </generatorConfiguration>  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 执行编译命令

通过完成配置文件的编写后,在mybatis-generator-core-1.3.2.jar同级目录,执行编译命令,就可以轻松完成又表生成实体类和xml的mapper文件啦。命令如下

java -jar mybatis-generator-core-1.3.2.jar -configfile generatorConfig.xml -overwrite
  • 1

注意:若是原来有对应的xml文件,新生成的文件会追加到原来的mapper文件后面,尼玛,我就被坑了一次,后来查看居然有相同的方法在xml文件里面,项目启动报错。 
相关包和文件请点击这里

言归正传
首先,我们在项目中创建一个jdbc.properties文件,可以将全部的数据库地址写入到此配置文件中

jdbc.driver=com.mysql.jdbc.Driver#服务器数据库#jdbc.url=jdbc:mysql://67.209.190.39:3306/twjitm?useUnicode=true&characterEncoding=utf-8#jdbc.username=root#jdbc.password=123456#本地数据库#jdbc.url=jdbc:mysql://127.0.0.1:3306/twjitm?useUnicode=true&characterEncoding=utf-8#本地服后台管理系统数据库地址jdbc.url-admin=jdbc:mysql://127.0.0.1:3306/admin?useUnicode=true&characterEncoding=utf-8jdbc.username-admin=rootjdbc.password-admin=123456#商城网站地址jdbc.url-shop=jdbc:mysql://127.0.0.1:3306/shop?useUnicode=true&characterEncoding=utf-8jdbc.username-shop=rootjdbc.password-shop=123456#正式服服务器地址#最大连接数c3p0.maxPoolSize=30000#最小连接数c3p0.minPoolSize=10#关闭连接后不自动commitc3p0.autoCommitOnClose=false#获取连接超时时间c3p0.checkoutTimeout=10000#当获取连接失败重试次数c3p0.acquireRetryAttempts=2
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

在进行配置
例如本例子中采用配置两套数据库来做测试,一个admin,一个shop两个数据源,在企业级开发中可能我们会对数据库采用很多分库分表策略,
其实原理都一样,
applicationContext.xml 中首先将properties文件加载进来,采用 context:property-placeholder 标签
可以同时加载多个这样的配置文件;下面就是我的项目中使用的,如有redis的配置文件,
applicationContext.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:mvc="http://www.springframework.org/schema/mvc"       xmlns:context="http://www.springframework.org/schema/context"       xsi:schemaLocation="http://www.springframework.org/schema/beans       http://www.springframework.org/schema/beans/spring-beans.xsd        http://www.springframework.org/schema/mvc        http://www.springframework.org/schema/mvc/spring-mvc.xsd       http://www.springframework.org/schema/context       http://www.springframework.org/schema/context/spring-context.xsd">    <mvc:annotation-driven/>    <!-- 切入点 -->    <context:property-placeholder            location="classpath:jdbc/jdbc.properties,classpath:redis/redis.properties"/>    <!--        <context:property-placeholder location="classpath:redis/redis.properties" ignore-unresolvable="true"/>    -->    <!--<bean class="com.twjitm.common.listener.StartupServerListener"></bean>--></beans>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

这样,我们就能够在xml文件中使用properties中定义的数据了,然而,我觉得上面介绍的内容可能大家都觉得太普遍了,其实都是为了使得mybatis配置多套数据源做准备工作,同时,我们在maven项目中集成这一个功能,在spring配置文件applicationContext-mybatis.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:tx="http://www.springframework.org/schema/tx"       xmlns:mvc="http://www.springframework.org/schema/mvc"       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/tx       http://www.springframework.org/schema/tx/spring-tx.xsd        http://www.springframework.org/schema/mvc        http://www.springframework.org/schema/mvc/spring-mvc.xsd">      <!-- 扫描service层 -->    <mvc:annotation-driven/>    <context:component-scan base-package="com.test.*.server" use-default-filters="false"/>    <!-- 数据库连接池 -->    <bean id="admin" class="com.mchange.v2.c3p0.ComboPooledDataSource">        <property name="driverClass" value="${jdbc.driver}"/>        <property name="jdbcUrl" value="${jdbc.url-admin}"/>        <property name="user" value="${jdbc.username-admin}"/>        <property name="password" value="${jdbc.password-admin}"/>        <property name="maxPoolSize" value="${c3p0.maxPoolSize}"/>        <property name="minPoolSize" value="${c3p0.minPoolSize}"/>        <property name="autoCommitOnClose" value="${c3p0.autoCommitOnClose}"/>        <property name="checkoutTimeout" value="${c3p0.checkoutTimeout}"/>        <property name="acquireRetryAttempts" value="${c3p0.acquireRetryAttempts}"/>    </bean>    <!--第二套数据源-->    <bean id="shop" class="com.mchange.v2.c3p0.ComboPooledDataSource">        <property name="driverClass" value="${jdbc.driver}"/>        <property name="jdbcUrl" value="${jdbc.url-shop}"/>        <property name="user" value="${jdbc.username-shop}"/>        <property name="password" value="${jdbc.password-shop}"/>        <property name="maxPoolSize" value="${c3p0.maxPoolSize}"/>        <property name="minPoolSize" value="${c3p0.minPoolSize}"/>        <property name="autoCommitOnClose" value="${c3p0.autoCommitOnClose}"/>        <property name="checkoutTimeout" value="${c3p0.checkoutTimeout}"/>        <property name="acquireRetryAttempts" value="${c3p0.acquireRetryAttempts}"/>    </bean>    <!--动态数据源的配置-->    <bean id="dynamicDataSource" class="com.test.common.mybatis.DynamicDataSource">        <property name="targetDataSources">            <map key-type="java.lang.String">                <entry value-ref="admin" key="admin"/>                <entry value-ref="shop" key="shop"/>            </map>        </property>        <property name="defaultTargetDataSource" ref="admin">        </property>    </bean>    <!-- 配置SqlSessionFactory对象 -->    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">        <!-- 注入数据库连接池 -->        <property name="dataSource" ref="dynamicDataSource"/>        <!-- 扫描model包 使用别名 -->        <property name="typeAliasesPackage" value="com.bufan.admin.*.entity"/>        <!-- 扫描sql配置文件:mapper需要的xml文件 -->        <!-- <property name="mapperLocations" value="classpath:mapper/*.xml"/>-->     <property name="mapperLocations" value="classpath:mapper/*/*.xml"/>        <property name="configurationProperties">            <props>                <prop key="mapUnderscoreToCamelCase">true</prop>            </props>        </property>        <!-- <property name="plugins" >             <array>                 <bean class="com.test.common.mybatis.mapperhelper.MapperInterceptor"/>             </array>         </property>-->    </bean>       <!--这个地方主要是用来用Mapper来替换xml文件形式的,与本例子无关-->   <!--<bean class="tk.mybatis.spring.mapper.MapperScannerConfigurer">        <property name="basePackage" value="com.bufan.admin.*.dao"/>        <property name="properties">            <value>                mappers=tk.mybatis.mapper.common.Mapper            </value>        </property>        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>    </bean>-->    <!-- 配置扫描Dao接口包,动态实现Dao接口,注入到spring容器中 -->   <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>       <property name="basePackage" value="com.test.admin.*.dao"/>    </bean>    <!-- 配置事务管理器 -->    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">        <!-- 注入数据库连接池 -->        <property name="dataSource" ref="dynamicDataSource"/>    </bean>    <!-- 配置基于注解的声明式事务 -->    <tx:annotation-driven transaction-manager="transactionManager"/></beans>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104

正如大家所看到的,添加了自定义一个类,一个是DynamicDataSource,其实DynamicDataSource,是继承了
spring的AbstractRoutingDataSource,充当了DataSource的路由中介, 能有在运行时, 根据某种key值来动态切换到真正的DataSource上。
在spring的官方文档上是这么介绍的
Abstract {@link javax.sql.DataSource} implementation that routes {@link #getConnection()}
calls to one of various target DataSources based on a lookup key. The latter is usually
(but not necessarily) determined through some thread-bound transaction context.
大概意思就是getConnection()根据查找lookup key键对不同目标数据源的调用,通常是通过(但不一定)某些线程绑定的事物上下文来实现。
 
通过这我们知道可以实现: 
      多数据源的动态切换,在程序运行时,把数据源数据源动态织入到程序中,灵活的进行数据源切换。 基于多数据源的动态切换,我们可以实现读写分离,这么做缺点也很明显,无法动态的增加数据源

DynamicDataSource.java 文件如下

public class DynamicDataSource extends AbstractRoutingDataSource {    @Override    protected Object determineCurrentLookupKey() {        System.out.println(CustomerContextHolder.getCustomerType());        return CustomerContextHolder.getCustomerType();    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

CustomerContextHolder.java文件内容输入,采用ThreadLocal模式来实现一个安全的线程访问,有关ThreadLocal类更多
内容,请点击这里

public class CustomerContextHolder {    public static final String DATASOURCE_ADMIN = "admin";    public static final String DATASOURCE_SHOP = "shop";    public static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();    public static void setCustomerType(String customerType) {        contextHolder.set(customerType);    }    public static String getCustomerType() {        return contextHolder.get();    }    public static void clearCustomerType() {        contextHolder.remove();    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

最后,比如要操作数据库的时候我们只需要在设置
  springMVC +mybatis+mysql多套数据源配置CustomerContextHolder.setCustomerType(CustomerContextHolder.DATASOURCE_SHOP);
就代表要操作shop这个库了。
 到此,我们就能实现mybatis动态的切换数据源。

           

相关文章:

  • 2021-06-26
  • 2021-06-03
  • 2021-08-15
  • 2021-10-09
  • 2021-11-24
  • 2021-11-19
  • 2022-03-07
  • 2019-03-28
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2022-02-12
  • 2021-08-29
  • 2021-11-25
  • 2021-09-16
  • 2021-10-31
相关资源
相似解决方案