spring+hibernate配置多數據源

spring+hibernate配置多數據源及多個事務過程

  • 在datasource.properties文件中增長數據庫配置
sqlServer.jdbc.url=jdbc:sqlserver://127.0.0.1:1433;databaseName=db_ceshi1
sqlServer.jdbc.user=sa
sqlServer.jdbc.password=sa
sqlServer.jdbc.initialPoolSize=5
sqlServer.jdbc.minPoolSize=5
sqlServer.jdbc.maxPoolSize=80
sqlServer.jdbc.checkoutTimeout=20000
sqlServer.jdbc.idleConnectionTestPeriod=120
sqlServer.jdbc.maxIdleTime=60
sqlServer.jdbc.maxStatements=6000
sqlServer.jdbc.testConnectionOnCheckout=false

sqlServer.jdbc.erms.driverClass=com.microsoft.sqlserver.jdbc.SQLServerDriver
sqlServer.jdbc.erms.url=jdbc:sqlserver://127.0.0.1:1433;databaseName=db_ceshi2
sqlServer.jdbc.erms.user=sa
sqlServer.jdbc.erms.password=sa
sqlServer.jdbc.erms.initialPoolSize=5
sqlServer.jdbc.erms.minPoolSize=5
sqlServer.jdbc.erms.maxPoolSize=80
sqlServer.jdbc.erms.checkoutTimeout=20000
sqlServer.jdbc.erms.idleConnectionTestPeriod=120
sqlServer.jdbc.erms.maxIdleTime=60
sqlServer.jdbc.erms.maxStatements=6000
sqlServer.jdbc.erms.testConnectionOnCheckout=false
  • 在spring.xml文件中配置數據源級事務
    <bean id="dataSourceSqlServer" class="com.mchange.v2.c3p0.ComboPooledDataSource"
        destroy-method="close">
        <property name="driverClass" value="${sqlServer.jdbc.driverClass}" />
        <property name="jdbcUrl" value="${sqlServer.jdbc.url}" />
        <property name="user" value="${sqlServer.jdbc.user}" />
        <property name="password" value="${sqlServer.jdbc.password}" />
        <property name="initialPoolSize" value="${sqlServer.jdbc.initialPoolSize}" />
        <property name="minPoolSize" value="${sqlServer.jdbc.minPoolSize}" />
        <property name="maxPoolSize" value="${sqlServer.jdbc.maxPoolSize}" />
        <property name="checkoutTimeout" value="${sqlServer.jdbc.checkoutTimeout}" />
        <property name="idleConnectionTestPeriod" value="${sqlServer.jdbc.idleConnectionTestPeriod}" />
        <property name="maxIdleTime" value="${sqlServer.jdbc.maxIdleTime}" />
        <property name="maxStatements" value="${sqlServer.jdbc.maxStatements}" />
        <property name="testConnectionOnCheckout" value="${sqlServer.jdbc.testConnectionOnCheckout}" />
    </bean>

    <bean id="dataSource" class="com.hebky.erms.util.core.DynamicDataSource">
        <property name="targetDataSources">
            <map key-type="java.lang.String">
                <entry key="dataSourceMySql" value-ref="dataSourceMySql" />
                <entry key="dataSourceSqlServer" value-ref="dataSourceSqlServer" />
            </map>
        </property>
        <property name="defaultTargetDataSource" ref="dataSourceSqlServer" />
    </bean>

    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="configLocation" value="classpath:hibernate.cfg.xml" />
        <!-- 經過掃描包的方式掃描全部實體類 -->
        <property name="packagesToScan">
            <list>
                <value>com.ceshi.*</value>
            </list>
        </property>
    </bean>

    <!-- 配置事務管理器 -->
    <bean id="transactionManager"
        class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory"></property>
        <property name="nestedTransactionAllowed" value="true"></property>
    </bean>

    <!-- 攔截器方式配配置事務 -->
    <tx:advice id="txadvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="add*" propagation="REQUIRED" />
            <tx:method name="save*" propagation="REQUIRED" />
            <tx:method name="saveRN*" propagation="REQUIRES_NEW" />
            <tx:method name="import*" propagation="REQUIRED" />
            <tx:method name="update*" propagation="REQUIRED" />
            <tx:method name="saveNS*" propagation="NOT_SUPPORTED" />
            <tx:method name="updateNS*" propagation="NOT_SUPPORTED" />
            <tx:method name="executeNS*" propagation="REQUIRED" />
            <tx:method name="updateRN*" propagation="REQUIRES_NEW" />
            <tx:method name="delete*" propagation="REQUIRED" no-rollback-for="NotImplementedException"/>
            <tx:method name="get*" read-only="true" propagation="REQUIRED" />
            <tx:method name="find*" read-only="true" propagation="REQUIRED" />
            <tx:method name="query*" read-only="true" propagation="REQUIRED" />
            <tx:method name="count*" read-only="true" propagation="REQUIRED" />
            <tx:method name="isNS*" read-only="true" propagation="NOT_SUPPORTED" />
            <tx:method name="*" read-only="true" />
        </tx:attributes>
    </tx:advice>
    <aop:config>
        <aop:pointcut id="serviceMethods"
            expression="execution(* com.ceshi..service..*.*(..))" />
        <aop:advisor advice-ref="txadvice" pointcut-ref="serviceMethods" />
    </aop:config>

    <!--從數據庫配置-->
    <bean id="dataSourcecm" class="com.mchange.v2.c3p0.ComboPooledDataSource" >
        <property name="driverClass" value="${sqlServer.jdbc.erms.driverClass}" />
        <property name="jdbcUrl" value="${sqlServer.jdbc.erms.url}" />
        <property name="user" value="${sqlServer.jdbc.erms.user}" />
        <property name="password" value="${sqlServer.jdbc.erms.password}" />
        <property name="initialPoolSize" value="${sqlServer.jdbc.erms.initialPoolSize}" />
        <property name="minPoolSize" value="${sqlServer.jdbc.erms.minPoolSize}" />
        <property name="maxPoolSize" value="${sqlServer.jdbc.erms.maxPoolSize}" />
        <property name="checkoutTimeout" value="${sqlServer.jdbc.erms.checkoutTimeout}" />
        <property name="idleConnectionTestPeriod" value="${sqlServer.jdbc.erms.idleConnectionTestPeriod}" />
        <property name="maxIdleTime" value="${sqlServer.jdbc.erms.maxIdleTime}" />
        <property name="maxStatements" value="${sqlServer.jdbc.erms.maxStatements}" />
        <property name="testConnectionOnCheckout" value="${sqlServer.jdbc.erms.testConnectionOnCheckout}" />
    </bean>

    <!--session工廠-->
    <bean id="sessionFactorycm" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" >
        <property name="dataSource" ref="dataSourcecm" />
        <!--包掃描,數據庫對應的實體類所在的包-->
        <!-- 經過掃描包的方式掃描全部實體類 -->
        <property name="packagesToScan">
            <list>
                <value>com.ceshi.*</value>
            </list>
        </property>
        <property name="hibernateProperties">
            <value>
                <!-- hibernate使用的數據庫方言(即鏈接哪一種數據庫) -->
                hibernate.dialect = org.hibernate.dialect.SQLServerDialect
                <!-- 自動更新數據庫表結構 -->
                hibernate.hbm2ddl.auto = update
                <!-- 後臺顯示sql語句,開發時使用-->
                hibernate.show_sql = true
                <!-- 是否格式化SQL -->
                hibernate.format_sql = true
            </value>
        </property>
    </bean>

    <!--事務管理器-->
    <bean id="transactionManagercm" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactorycm"/>
    </bean>

    <!-- 配置事務通知屬性 -->
    <tx:advice id="transactionAdvicecm" transaction-manager="transactionManagercm">
        <!-- 定義事務傳播屬性 -->
        <tx:attributes>
            <tx:method name="add*" propagation="REQUIRED" />
            <tx:method name="save*" propagation="REQUIRED" />
            <tx:method name="saveRN*" propagation="REQUIRES_NEW" />
            <tx:method name="import*" propagation="REQUIRED" />
            <tx:method name="update*" propagation="REQUIRED" />
            <tx:method name="saveNS*" propagation="NOT_SUPPORTED" />
            <tx:method name="updateNS*" propagation="NOT_SUPPORTED" />
            <tx:method name="executeNS*" propagation="REQUIRED" />
            <tx:method name="updateRN*" propagation="REQUIRES_NEW" />
            <tx:method name="delete*" propagation="REQUIRED" no-rollback-for="NotImplementedException"/>
            <tx:method name="get*" read-only="true" propagation="REQUIRED" />
            <tx:method name="find*" read-only="true" propagation="REQUIRED" />
            <tx:method name="query*" read-only="true" propagation="REQUIRED" />
            <tx:method name="count*" read-only="true" propagation="REQUIRED" />
            <tx:method name="isNS*" read-only="true" propagation="NOT_SUPPORTED" />
            <tx:method name="*" read-only="true" />
        </tx:attributes>
    </tx:advice>

    <!-- 配置事務切面 -->
    <aop:config>
        <aop:advisor pointcut="execution(* com.ceshi..service..*.*(..))" advice-ref="transactionAdvicecm"/>
    </aop:config>
  • 建立DatabaseContextHolder類
class DatabaseContextHolder {
    public static final String DATA_SOURCE_SQLSERVER = "dataSourceSqlServer";
    public static final String DATA_SOURCE_ERMS = "dataSourcecm";


    private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>(); // 線程本地環境

    /**
     * 設置數據源類型
     *
     * @param customerType 數據源類型
     */
    public static void setCustomerType(String customerType) {
        contextHolder.set(customerType);
    }

    /**
     * 獲取數據源類型
     *
     * @return
     */
    static String getCustomerType() {
        return contextHolder.get();
    }

    /**
     * 清除數據源類型
     */
    public static void clearCustomerType() {
        contextHolder.remove();
    }
}
  • 建立DynamicDataSource繼承AbstractRoutingDataSource獲取動態數據源
public class DynamicDataSource extends AbstractRoutingDataSource {

    /**
     * 在進行DAO操做前,經過上下文環境變量,得到數據源的類型
     */
    @Override
    protected Object determineCurrentLookupKey() {
        return DatabaseContextHolder.getCustomerType();
    }

}
  • 在BaseDao中注入session便可
public abstract class BaseDao implements IBaseDao {

    @Resource
    private SessionFactory sessionFactory;// 從容器中注入session工廠【無需get,set方法】

    @Resource
    private SessionFactory sessionFactorycm;

    /**
     * 向子類暴露的接口獲用來獲取session
     *
     * @return session
     */
    protected Session getSession() {
        // 事務必須是開啓的(Required),不然獲取不到
            return sessionFactory.getCurrentSession();
    }

    //注入第二個session
     protected Session getSessionFactorycm(){
            return sessionFactorycm.getCurrentSession();
        }


    /**
     * 保存實體
     *
     * @param t 實體參數
     */
    public <T> void save(T t) {
        getSession().save(t);
    }
    
    public <T> void saveTwo(T t){
        getSessionFactorycm().save(T);
    }
}

配置多數據源完成java

相關文章
相關標籤/搜索