Struts2 + Spring3 + MyBatis3 动态切换 多数据源

简介:

        Spring动态配置多数据源,即在大型应用中对数据进行切分,并且采用多个数据库实例进行管理,这样可以有效提高系统的水平伸缩性。而这样的方案就会不 同于常见的单一数据实例的方案,这就要程序在运行时根据当时的请求及系统状态来动态的决定将数据存储在哪个数据库实例中,以及从哪个数据库提取数据。 

Spring对于多数据源,以数据库表为参照,大体上可以分成两大类情况: 
  一是,表级上的跨数据库。即,对于不同的数据库却有相同的表(表名和表结构完全相同)。 
  二是,非表级上的跨数据库。即,多个数据源不存在相同的表。 

多数据源实现

        Spring2.x的版本中采用Proxy模式,就是我们在方案中实现一个虚拟的数据源,并且 用它来封装数据源选择逻辑,这样就可以有效地将数据源选择逻辑从Client中分离出来。Client提供选择所需的上下文(因为这是Client所知道 的),由虚拟的DataSource根据Client提供的上下文来实现数据源的选择。 
  具体的实现就是,虚拟的DataSource仅需继承AbstractRoutingDataSource实现determineCurrentLookupKey()在其中封装数据源的选择逻辑。 

配置方法:

1、数据源的名称常量类:

 

  1. /** 
  2.  * 数据源的名称常量类 
  3.  * @author Administrator 
  4.  * 
  5.  */  
  6. public class DataSourceConst {  
  7.     public static final String USERDB = "USERDB";  
  8.     public static final String SCOREDB = "SCOREDB";  
  9. }  

 

 


2、改变数据源名称类:

 

 

  1. /** 
  2.  * 改变数据源的名称类 
  3.  * @author Administrator 
  4.  * 
  5.  */  
  6. public class DataSourceHandle {  
  7.     /** 
  8.      * 线程本地环境 
  9.      */  
  10.     @SuppressWarnings("unchecked")  
  11.     private static final ThreadLocal contextHolder = new ThreadLocal();  
  12.   
  13.     /** 
  14.      * 设置数据源类型 
  15.      * @param dataSourceType 
  16.      */  
  17.     @SuppressWarnings("unchecked")  
  18.     public static void setDataSourceType(String dataSourceType) {  
  19.         contextHolder.set(dataSourceType);  
  20.     }  
  21.   
  22.     /** 
  23.      * 获取数据源类型 
  24.      * @return 
  25.      */  
  26.     public static String getDataSourceType() {  
  27.         return (String) contextHolder.get();  
  28.     }  
  29.   
  30.     /** 
  31.      * 清除数据源类型 
  32.      */  
  33.     public static void clearDataSourceType() {  
  34.         contextHolder.remove();  
  35.     }  
  36. }  


3、动态数据源类:

 

 

  1. import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;  
  2.   
  3. /** 
  4.  * 动态数据源类 
  5.  * 这个类必须继承AbstractRoutingDataSource, 
  6.  * 且实现方法 determineCurrentLookupKey,该方法返回一个Object,一般是返回字符串 
  7.  * @author Administrator 
  8.  * 
  9.  */  
  10. public class DynamicDataSource extends AbstractRoutingDataSource {  
  11.   
  12.     @Override  
  13.     protected Object determineCurrentLookupKey() {  
  14.         // 在进行DAO操作前,通过上下文环境变量,获得数据源的类型  
  15.         return DataSourceHandle.getDataSourceType();  
  16.     }  
  17. }  

 

4、 spring配置文件中配置多个数据源 

 

  1. <!-- 数据源基本配置 -->  
  2. <bean id="basicDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">  
  3.     <property name="driverClass" value="com.mysql.jdbc.Driver" />  
  4.     <property name="minPoolSize" value="2" />  
  5.     <property name="maxPoolSize" value="20" />  
  6.     <property name="maxIdleTime" value="1800" />  
  7.     <property name="acquireIncrement" value="2" />  
  8.     <property name="maxStatements" value="0" />  
  9.     <property name="initialPoolSize" value="3" />  
  10.     <property name="idleConnectionTestPeriod" value="1800" />  
  11.     <property name="acquireRetryAttempts" value="30" />  
  12.     <property name="breakAfterAcquireFailure" value="true" />  
  13.     <property name="testConnectionOnCheckout" value="false" />  
  14. </bean>  
  15. <!-- csoa dataSource -->  
  16. <bean id="dataSourceUser" parent="basicDataSource">  
  17.     <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/userdb" />  
  18.     <property name="user" value="root" />  
  19.     <property name="password" value="admin" />  
  20. </bean>  
  21. <!-- wa dataSource -->  
  22. <bean id="dataSourceScore" parent="basicDataSource">  
  23.     <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/scoredb" />  
  24.     <property name="user" value="root" />  
  25.     <property name="password" value="admin" />  
  26. </bean>  
  27. <!-- data source 抽象类 -->  
  28. <bean id="dataSource" class="com.webterren.csoa.util.dbutil.DynamicDataSource">  
  29.     <property name="targetDataSources">  
  30.         <map key-type="java.lang.String">  
  31.             <entry value-ref="dataSourceUser" key="USERDB"></entry>  
  32.             <entry value-ref="dataSourceScore" key="SCOREDB"></entry>  
  33.         </map>  
  34.     </property>  
  35.     <property name="defaultTargetDataSource" ref="dataSourceUser"></property><!-- 默认数据源 -->  
  36. </bean>  
  37.   
  38. <!-- MyBatis SQLSessionFactory -->  
  39. <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">  
  40.     <property name="dataSource" ref="dataSource"></property>  
  41.     <property name="configLocation" value="classpath:config/mybatis/Configuration.xml" />  
  42. </bean>  

这里依个人情况而定

 

测试:

1、SQL语句:

 

  1. <select id="countUser" resultType="int">  
  2.     select count(*) from user  
  3. </select>  
  4.   
  5. <select id="countScore" resultType="int">  
  6.     select count(*) from score  
  7. </select>  

 

2、测试方法

 

  1. SqlSession session = null;  
  2. //user  
  3. DataSourceHandle.setDataSourceType(DataSourceConst.USERDB);  
  4. session = this.getSqlSession();  
  5. int countUser = (Integer)session.selectOne("DbTest.countUser","");  
  6. session.close();  
  7. //score  
  8. DataSourceHandle.setDataSourceType(DataSourceConst.SCOREDB);  
  9. session = this.getSqlSession();  
  10. int countScore = (Integer)session.selectOne("DbTest.countScore","");  
  11. session.close();  
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值