• 基于Spring框架的简单多数据源切换解决办法


    基于Spring框架的简单多数据源切换解决办法

    Spring框架JDBC包提供了一个抽象类AbstractRoutingDataSource提供了动态切换数据库的基础方法。我们仅仅需要实现一个简单的数据源选择算法就可以轻松的利用Spring框架实现数据源切换了。

    Spring支持每次被操作的单数据源的事务。

    1.继承AbstractRoutingDataSource并实现方法determineCurrentLookupKey()

     1 package dev.tinyz.datasource;
     2 
     3 import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
     4 
     5 /**
     6  * Created by TinyZ on 2014/7/28.
     7  */
     8 public class MultiDataSource extends AbstractRoutingDataSource {
     9     @Override
    10     protected Object determineCurrentLookupKey() {
    11         return MultiContextHolder.getDataSourceType();
    12     }
    13 }
    View Code

    2.实现一个数据源选择算法。示例提供了一个简单的代码选择数据源示例

     1 package dev.tinyz.datasource;
     2 
     3 /**
     4  * Created by TinyZ on 2014/7/28.
     5  */
     6 public class MultiContextHolder {
     7 
     8     // 定义数据源 - 每个数据源都要在这里注册
     9     public static final String DATA_SOURCE_1 = "1";// 对应在beans.xml里面注册的数据源的key
    10     public static final String DATA_SOURCE_2 = "2";
    11 
    12     // ThreadLocal:用于解决线程安全问题。每个线程都会拥有一个独立的变量副本。线程内部可以独立的改变,而不影响其他线程
    13     public static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();
    14 
    15     public static void setDataSourceType(String type) {
    16         contextHolder.set(type);
    17     }
    18 
    19     public static String getDataSourceType() {
    20         return contextHolder.get();
    21     }
    22 }
    View Code

    3.Spring配置(仅供参考)  **最重要的部分 - 包含了定义多数据源,配置多数据源路由器,设置事务支持

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <beans xmlns="http://www.springframework.org/schema/beans"
     3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
     4     xmlns:tx="http://www.springframework.org/schema/tx" xmlns:task="http://www.springframework.org/schema/task"
     5     xsi:schemaLocation="
     6         http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
     7         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
     8         http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
     9         http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd">
    10 
    11     <!-- Configure all properties files here, wildcards like *.properties are also allowed -->
    12     <!-- <context:property-placeholder location="file:conf/conf.properties" /> -->
    13 
    14     <!-- 设置数据源 --><!-- BoneCP configuration -->
    15     <bean id="dataSource1" class="com.jolbox.bonecp.BoneCPDataSource" destroy-method="close">
    16         <property name="driverClass" value="com.mysql.jdbc.Driver" />
    17         <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/black?useUnicode=true&amp;characterEncoding=UTF-8" />
    18         <property name="username" value="root" />
    19         <property name="password" value="" />
    20         <property name="idleConnectionTestPeriodInMinutes" value="60" />
    21         <property name="idleMaxAgeInMinutes" value="240" />
    22         <property name="maxConnectionsPerPartition" value="10" />
    23         <property name="minConnectionsPerPartition" value="5" />
    24         <property name="partitionCount" value="5" />
    25         <property name="acquireIncrement" value="5" />
    26         <property name="statementsCacheSize" value="100" />
    27         <!--<property name="releaseHelperThreads" value="3" />-->
    28     </bean>
    29     <bean id="dataSource2" class="com.jolbox.bonecp.BoneCPDataSource" destroy-method="close">
    30         <property name="driverClass" value="com.mysql.jdbc.Driver" />
    31         <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/black1?useUnicode=true&amp;characterEncoding=UTF-8" />
    32         <property name="username" value="root" />
    33         <property name="password" value="" />
    34         <property name="idleConnectionTestPeriodInMinutes" value="60" />
    35         <property name="idleMaxAgeInMinutes" value="240" />
    36         <property name="maxConnectionsPerPartition" value="10" />
    37         <property name="minConnectionsPerPartition" value="5" />
    38         <property name="partitionCount" value="5" />
    39         <property name="acquireIncrement" value="5" />
    40         <property name="statementsCacheSize" value="100" />
    41         <!--<property name="releaseHelperThreads" value="3" />-->
    42     </bean>
    43 
    44     <!-- 设置abstractRoutingDataSource注入两个变量 -->
    45     <bean id="dataSource" class="dev.tinyz.datasource.MultiDataSource">
    46         <property name="targetDataSources">
    47             <map key-type="java.lang.String">
    48                 <entry key="1" value-ref="dataSource1"></entry>
    49                 <entry key="2" value-ref="dataSource2"></entry>
    50             </map>
    51         </property>
    52         <property name="defaultTargetDataSource" ref="dataSource1"/>
    53     </bean>
    54     
    55     <!-- 设置缓存工厂 - 数据来源于 dataSource -->
    56     <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    57         <property name="dataSource" ref="dataSource" />
    58     </bean>
    59     <!-- Spring框架    数据库 JDBC事务管理器 -->
    60     <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    61         <property name="dataSource" ref="dataSource" />
    62     </bean>
    63     <!-- Spring框架    事务模板 -->
    64     <bean id="txTemplate" class="org.springframework.transaction.support.TransactionTemplate">
    65         <property name="transactionManager" ref="txManager"></property>
    66         <property name="propagationBehaviorName" value="PROPAGATION_REQUIRED"></property>
    67     </bean>
    68     <!-- Spring框架    启动使用注解实现声明式事务管理的支持 -->
    69     <tx:annotation-driven transaction-manager="txManager" />
    70 
    71     <!-- Server beans -->
    72 
    73     <!-- 配置容器  不需要任何属性            The Spring application context-->
    74     <bean id="springContext" class="dev.tinyz.config.AppContext"></bean>
    75 
    76     <!-- Mybatis Bean -->
    77     <bean id="baseMapper" class="org.mybatis.spring.mapper.MapperFactoryBean" abstract="true" lazy-init="true">
    78         <property name="sqlSessionFactory" ref="sqlSessionFactory"/>
    79     </bean>
    80     <bean id="useMapper" parent="baseMapper">
    81         <property name="mapperInterface" value="dev.tinyz.persistence.mapper.UserMapper"/>
    82     </bean>
    83 
    84     <!-- 注解配置 -->
    85     <context:annotation-config />
    86     <!-- 注解扫描 基础包-dev.tinyz.persistence -->
    87     <context:component-scan  base-package="dev.tinyz.persistence" />
    88 </beans>
    View Code
    dataSource 是我们定义的MultiDataSource的实例。拥有两个属性targetDataSources和defaultTargetDataSource,这两个属性名都不能修改。因为AbstractRoutingDataSource里面设置的参数是依赖Spring注入的。有需要的朋友可以去查看Spring的源码
    AppContext 是程序实现的Spring单例。继承ApplicationContextAware
    baseMapper 定义了Mybatis-Spring桥里面的一个抽象类。用于子类实现映射接口

    4.简单的测试代码(示例)

    1 // 测试
    2         final UserMapper userMapper = (UserMapper) AppContext.getBean("useMapper");
    3         // 切换到数据源1
    4         MultiContextHolder.setDataSourceType(MultiContextHolder.DATA_SOURCE_1);
    5         // 查询数据库
    6         MemUser tinyz1 = userMapper.selectByAccount("tinyz1");
    View Code

    ps:以下的内容是笔者提供的示例。假如不需要的话,可以忽略。O(∩_∩)O哈哈~。写的很简单。

    示例的需求:

    操作系统:Win 7 64bit

    编辑工具:Intellij IDEA 13.1

    数据库: MYSQL 5.6

    ps:使用IDEA导出了一份eclipse的配置。但是不知道能不能用eclipse打开。。未测试

    类库依赖:

    BoneCp 0.8.0

    Mybatis 3.2.7

    Mybatis-Spring 1.2.2

    SpringFramework 3.2.10

    Mysql-Connecter-java 3.1.31

    ps:所有的依赖全部都是依靠Maven的。所以你懂的。

    Main就是实例的测试代码。beans.xml配置文件里面的各个数据源的访问地址,账户和密码。自行修改

    示例源代码下载地址:示例-基于Spring框架的简单多数据源切换解决办法

    作者:TinyZ
    出处:http://www.cnblogs.com/zou90512/
    关于作者:努力学习,天天向上。不断探索学习,提升自身价值。记录经验分享。
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接
    如有问题,可以通过 zou90512@126.com 联系我,非常感谢。
    笔者网店: http://aoleitaisen.taobao.com. 欢迎广大读者围观

  • 相关阅读:
    MSER
    resize和reserve的区别
    Rect
    U盘文件或目录损坏且无法读取怎么解决
    信道估计
    ann
    仿射变换详解 warpAffine
    opencv新版本的数据结构
    大津法
    php红包
  • 原文地址:https://www.cnblogs.com/zou90512/p/3878375.html
Copyright © 2020-2023  润新知