zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    Java入门第二阶段总结
    POj3017 dp+单调队列优化
    CH5701 开车旅行(倍增dp+set)
    dp优化---四边形不等式与决策单调性
    CH5E07 划分大理石(背包dp+二进制拆分)
    POJ1185 炮兵阵地(状压dp)
    CH5501 环路运输(单调栈)
    poj3585 Accumulation Degree(换根dp)
    CH5105 Cookies (线性dp)
    反射
  • 原文地址:https://www.cnblogs.com/xuhn/p/2770627.html
Copyright © 2011-2022 走看看