Spring配置多数据源的方式和具体使用过程

1、数据源的名称常量类

    public enum DynamicDataSourceGlobal {

    1.     ORCL,   
    2. ISC
    3. }


     

    2、建立一个获得和设置上下文环境的类,主要负责改变上下文数据源的名称

        public class DynamicDataSourceHolder {

    1. // 线程本地环境
    2. private static final ThreadLocal<DynamicDataSourceGlobal> contextHolder = new
    3.
    4. // 设置数据源类型
    5. public static void
    6. "DataSourceType cannot be null");
    7. contextHolder.set(dataSourceType);
    8. }
    9.
    10. // 获取数据源类型
    11. public static
    12. return
    13. }
    14.
    15. // 清除数据源类型
    16. public static void
    17. contextHolder.remove();
    18. }


     

    3、建立动态数据源类,注意,这个类必须继承AbstractRoutingDataSource,且实现方法 determineCurrentLookupKey,该方法返回一个Object,一般是返回字符串

        public class DynamicDataSource extends AbstractRoutingDataSource {

    1. @Override
    2. protected
    3. return
    4. }
    5.
    6. }


    4、编写spring的配置文件配置多个数据源

         <!-- 数据源相同的内容 -->

    1. "parentDataSource"
    2. class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    3. "driverClass"
    4. "oracle.jdbc.pool.OracleConnectionPoolDataSource"
    5. "url" value="jdbc:oracle:thin:@127.0.0.1:1521:orcl"
    6. "user" value="isc_v10"
    7. "password" value="isc"
    8. </bean>
    9.
    10. <!-- 数据源 -->
    11. "orclDataSource" parent="parentDataSource">
    12. "user" value="orcl"
    13. "password" value="orcl"
    14. </bean>
    15.
    16. <!-- 数据源 -->
    17. "iscDataSource" parent="parentDataSource">
    18. "user" value="isc_v10"
    19. "password" value="isc"
    20. </bean>
    21.
    22. <!-- 编写spring 配置文件的配置多数源映射关系 -->
    23. "dataSource" class="com.wy.config.DynamicDataSource">
    24. "targetDataSources">
    25. "java.lang.String">
    26. "ORCL" value-ref="orclDataSource"></entry>
    27. "ISC" value-ref="iscDataSource"></entry>
    28. </map>
    29. </property>
    30. "defaultTargetDataSource" ref="orclDataSource">
    31. </property>
    32. </bean>
    33.
    34. "sessionFactory"
    35. class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
    36. "dataSource" ref="dataSource"
    37. </bean>


     

    5、使用

       @Test


    利用AbstractRoutingDataSource实现动态数据源切换 (Spring+Hibernate)_java代码


    1. public void
    2. // hibernate创建实体
    3. // 设置为另一个数据源
    4. new
    5.
    6. "WY");
    7. "BJ");
    8.
    9. // 使用dao保存实体
    10.
    11. // 设置为另一个数据源
    12.
    13. // 使用dao保存实体到另一个库中
    14.
    15. }




    spring 的AbstractRoutingDataSource解决了这个问题。

    原理如图:


    利用AbstractRoutingDataSource实现动态数据源切换 (Spring+Hibernate)_spring_02

     

    spring.xml设置sessionFactory的dataSource属性为动态数据源即可。

    springAbstractRoutingDataSource类增加了一个getTargetDataSources方法,获取当前数据源详细信息,在其基础上修改数据库名称、用户名、密码即可,不用每次设置一堆参数。


    利用AbstractRoutingDataSource实现动态数据源切换 (Spring+Hibernate)_java代码


    1. Map<String, ComboPooledDataSource> targetDataSources = dynamicDataSource  
    2. .getTargetDataSources();
    3. if (targetDataSources == null) {
    4. new
    5. "baseDataSource", baseDataSource);
    6. }
    7. targetDataSources.put(dataSourceName, subSystemDataSource);
    8. dynamicDataSource.setTargetDataSources(targetDataSources);
    9. dynamicDataSource.afterPropertiesSet();

     

    AbstractRoutingDataSource参数后要调用afterPropertiesSet()方法,spring容器才会进行加载操作。

     

    在动态设置数据源方面,可以通过两种方式实现:

    1. 在action(项目使用struts)中进行设置,可以确保在每个servlet线程中数据源是一致的。
    2. 以aop方式,对service方法进行拦截,根据需求设置不同数据源。