Spring Hibernate多数据源配置

Spring2.0.1以后的版本已经支持配置多数据源,并且可以在运行的时候动态加载不同的数据源。通过继承AbstractRoutingDataSource就可以实现多数据源的动态转换。目前做的项目就是需要访问12个数据源,每个数据源的表结构都是相同的,所以要求数据源的变动对于编码人员来说是透明,也就是说同样SQL语句在不同的环境下操作的数据库是不一样的。具体的配置如下:

一、首先需要写一个静态的键值对照类:

 package cn.sunline.suncard.sde.dp.db;  

  
public class DataSourceMap {  
    public static final String acd="ACD";  
    public static final String trm= "TRM";  

 这个类主要在使用的时候当作获得数据源的标志使用。

 二、建立一个获得和设置上下文的类:

package cn.sunline.suncard.sde.dp.db;

/**
 * 数据源容器类
 * 
@author    tpf
 * 
@version   1.0  2012-8-27
 * 
@see       [相关类/方法]
 * 
@since     [产品/模块版本] 
 
*/
public class CustomerContextHolder {
    /**
     * 数据库连接配置容器
     
*/
    private static ThreadLocal contextHolder = new ThreadLocal();
    
    public static void setCustomerType(String customerType) {  
        contextHolder.set(customerType);
    }  
           
    public static String getCustomerType() {  
        return (String) contextHolder.get();
    }  
           
    public static void clearCustomerType() {  
        contextHolder.remove();
    } 

 这个主要负责设置上下文环境和获得上下文环境。 

三、建立动态数据源类,这个类必须继承AbstractRoutingDataSource

 package cn.sunline.suncard.sde.dp.db;


import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

/**
 * 动态数据源
 * 
@author    tpf
 * 
@version   1.0  2012-8-27
 * 
@see       [相关类/方法]
 * 
@since     [产品/模块版本] 
 
*/
public class DynamicDataSource extends AbstractRoutingDataSource {

    /* (non-Javadoc)
     * @see org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource#determineCurrentLookupKey()
     
*/
    @Override
    protected Object determineCurrentLookupKey() {
        String customerType = "";
        if(CustomerContextHolder.getCustomerType() != null) {
            customerType = CustomerContextHolder.getCustomerType().toString();
        }
        return customerType;
    }
}

 这个类实现了determineCurrentLookupKey方法,该方法返回一个Object,一般是返回字符串,也可以是枚举类型。该方法中直接使用了CustomerContextHolder.getCustomerType()方法获得上下文环境并直接返回。 

四、编写spring的配置文件配置数据源

    <bean id="hibernateInterceptor" class="cn.sunline.suncard.sde.dp.interceptor.HibernateInterceptor"></bean>
    <bean id="lobHandler" class="org.springframework.jdbc.support.lob.DefaultLobHandler" lazy-init="true" />
    
    <bean id="propertyConfigurer"
        class
="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
        dependency-check
="none">
        <property name="fileEncoding" value="UTF-8" />
        <property name="locations">
            <list>
                <value>/WEB-INF/config/jdbc.properties</value>
            </list>
        </property>
    </bean>
    <!-- 
    <bean id="acdDataSource" class="cn.sunline.suncard.sde.dp.db.ProxoolDataSourceImpl">
        <property name="driver">
            <value>${acdDataSource.driverClassName}</value>
        </property>
        <property name="driverUrl">
            <value>${acdDataSource.url}</value>
        </property>
        <property name="user">
            <value>${acdDataSource.username}</value>
        </property>
        <property name="password">
            <value>${acdDataSource.password}</value>
        </property>
        <property name="prototypeCount">
            <value>${acdDataSource.protoconn}</value>
        </property>
        <property name="maximumConnectionCount">
            <value>${acdDataSource.maxconn}</value>
        </property>
        <property name="minimumConnectionCount">
            <value>${acdDataSource.minconn}</value>
        </property>
        <property name="simultaneousBuildThrottle">
            <value>${acdDataSource.simultaneousBuildThrottle}</value>
        </property>
        <property name="trace">
            <value>false</value>
        </property>
        <property name="verbose">
            <value>true</value>
        </property>
    </bean>
    
    <bean id="trmDataSource" class="cn.sunline.suncard.sde.dp.db.ProxoolDataSourceImpl">
        <property name="driver">
            <value>${trmDataSource.driverClassName}</value>
        </property>
        <property name="driverUrl">
            <value>${trmDataSource.url}</value>
        </property>
        <property name="user">
            <value>${trmDataSource.username}</value>
        </property>
        <property name="password">
            <value>${trmDataSource.password}</value>
        </property>
        <property name="prototypeCount">
            <value>${trmDataSource.protoconn}</value>
        </property>
        <property name="maximumConnectionCount">
            <value>${trmDataSource.maxconn}</value>
        </property>
        <property name="minimumConnectionCount">
            <value>${trmDataSource.minconn}</value>
        </property>
        <property name="simultaneousBuildThrottle">
            <value>${trmDataSource.simultaneousBuildThrottle}</value>
        </property>
        <property name="trace">
            <value>false</value>
        </property>
        <property name="verbose">
            <value>true</value>
        </property>
    </bean>
     
-->
    
    <bean id="acdDataSource2" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName">
            <value>${acdDataSource.driverClassName}</value>
        </property>
        <property name="url">
            <value>${acdDataSource.url}</value>
        </property>
        <property name="username">
            <value>${acdDataSource.username}</value>
        </property>
        <property name="password">
            <value>${acdDataSource.password}</value>
        </property>
    </bean>
    
    <bean id="trmDataSource2" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName">
            <value>${trmDataSource.driverClassName}</value>
        </property>
        <property name="url">
            <value>${trmDataSource.url}</value>
        </property>
        <property name="username">
            <value>${trmDataSource.username}</value>
        </property>
        <property name="password">
            <value>${trmDataSource.password}</value>
        </property>
    </bean>
    
    
    <bean id="dataSource" class="cn.sunline.suncard.sde.dp.db.DynamicDataSource">  
        <property name="targetDataSources">  
           <map key-type="java.lang.String">  
              <entry key="ACD" value-ref="acdDataSource2"/>
              <entry key="TRM" value-ref="trmDataSource2"/>
           </map>  
        </property>  
        <property name="defaultTargetDataSource" ref="acdDataSource2"/>  
     </bean>
    
    
    <!-- sessionFactory配置开始 -->
    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="lobHandler" ref="lobHandler"/>
        <!-- <property name="configLocation" value="/WEB-INF/config/hibernate.cfg.xml"/> -->
        <property name="entityInterceptor">   
            <ref bean="hibernateInterceptor"/>  
        </property>
        <property name="dataSource">
            <ref bean="dataSource" />
        </property>
        <property name="hibernateProperties">
           <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.Oracle9Dialect</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.connection.useUnicode">true</prop>
                <prop key="hibernate.connection.characterEncoding">UTF-8</prop>
                <prop key="hibernate.connection.release_mode">auto</prop>
           </props>
          </property>
          <property name="mappingResources">
           <list>
            <value>cn/sunline/suncard/sde/dp/hbm/DpStrategy.hbm.xml</value>
            <value>cn/sunline/suncard/sde/dp/hbm/TrmUser.hbm.xml</value>
            <value>cn/sunline/suncard/sde/dp/hbm/DpDatapart.hbm.xml</value>
            <value>cn/sunline/suncard/sde/dp/hbm/TrmAuthtrxnlog.hbm.xml</value>
           </list>
          </property>
    </bean>

    <!--配置事务管理器  -->
    <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory">
            <ref bean="sessionFactory"/>
        </property>
    </bean>
    
    <!--配置事务管理的特性(隔离级别,传播特性...)  -->
    <tx:advice id="transAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="find*" read-only="true"/>
            <tx:method name="get*" read-only="true"/>
            <tx:method name="query*" read-only="true"/>
            <tx:method name="add*" propagation="REQUIRED" rollback-for="Exception"/>
            <tx:method name="read*" propagation="REQUIRED" rollback-for="Exception"/>
            <tx:method name="del*" propagation="REQUIRED" rollback-for="Exception"/>
            <tx:method name="edit*" propagation="REQUIRED" rollback-for="Exception"/>
            <tx:method name="save*" propagation="REQUIRED" rollback-for="Exception"/>
            <tx:method name="update*" propagation="REQUIRED" rollback-for="Exception"/>
            <tx:method name="insert*" propagation="REQUIRED" rollback-for="Exception"/>
            <tx:method name="id*" propagation="REQUIRED" rollback-for="Exception"/>            
            <tx:method name="*" propagation="REQUIRED" read-only="true" rollback-for="Exception"/>
        </tx:attributes>
    </tx:advice>
    
    
    
    
    <!--配置多数据源的事务拦截器-->      
    <aop:config>
        <aop:pointcut expression="execution(* cn.sunline.suncard.sde.dp.dao.impl.*.*(..))" id="managerpc"/>
        <aop:advisor advice-ref="transAdvice" pointcut-ref="managerpc"/>

    </aop:config> 

 在项目中对于编码人员对多数据源的切换可以做成透明的,操作同样的dao,就可以访问不同的数据库了。

转载:http://blog.csdn.net/tpfpcwl/article/details/7915389

原文地址:https://www.cnblogs.com/xuhn/p/2770627.html