天天看點

spring 多資料源 ,mybatis和hibernet版本mybatis版本hibernet 版本

1.資料源配置:

jdbc_multiple.properties:

 2.spring-mybatis.xml配置:

  

3.dbcontextholder類(作用是設定你目前的資料源)

4.使用方式:當你需要進行crud等資料庫操作的之前 設定你需要使用的資料源即可

例: 

其實再進行項目開發的時候,一個項目有可能不止用到一個資料源,為了提高資料庫的水準伸縮性,需要對多個資料庫執行個體進行管理,需要配置多資料源。

     1. 配置多個資料源

     這裡以兩個c3p0資料庫連接配接池的資料源作為執行個體。在spring架構下使用c3p0的資料庫需要加入c3p0-0.9.1.2.jar(現在最新的)這個支援包。這裡以資料同步項目為例:

   資料來源庫的連接配接池資料源配置:

spring 多資料源 ,mybatis和hibernet版本mybatis版本hibernet 版本

<bean id="datasourcefrom" class="com.mchange.v2.c3p0.combopooleddatasource">  

    <property name="driverclass" value="${jdbc.driver}" />  

    <property name="jdbcurl" value="${jdbc.from.url}" />  

    <property name="user" value="${jdbc.from.username}" />  

    <property name="password" value="${jdbc.from.password}" />  

    <property name="autocommitonclose" value="true" />  

    <property name="checkouttimeout" value="${cpool.checkouttimeout}" />  

    <property name="initialpoolsize" value="${cpool.minpoolsize}" />  

    <property name="minpoolsize" value="${cpool.minpoolsize}" />  

    <property name="maxpoolsize" value="${cpool.maxpoolsize}" />  

    <property name="maxidletime" value="${cpool.maxidletime}" />  

    <property name="acquireincrement" value="${cpool.acquireincrement}" />  

    <property name="maxidletimeexcessconnections" value="${cpool.maxidletimeexcessconnections}" />  

</bean>  

 資料插入庫的連接配接池資料源配置:

spring 多資料源 ,mybatis和hibernet版本mybatis版本hibernet 版本

<bean id="datasourceto" class="com.mchange.v2.c3p0.combopooleddatasource">  

    <property name="jdbcurl" value="${jdbc.to.url}" />  

    <property name="user" value="${jdbc.to.username}" />  

    <property name="password" value="${jdbc.to.password}" />  

   注意:上面url,user,password等值是從classpath下的jdbc.properties中取得的。

   通過spring擷取屬性檔案中的值,以供配置檔案使用:

spring 多資料源 ,mybatis和hibernet版本mybatis版本hibernet 版本

<bean class="org.springframework.beans.factory.config.propertyplaceholderconfigurer">  

    <property name="locations" value="classpath:jdbc.properties" />  

     2. 擴充spring的abstractroutingdatasource抽象類,實作動态資料源。

    abstractroutingdatasource中的抽象方法determinecurrentlookupkey是實作資料源的route的核心.這裡對該方法進行override。

spring 多資料源 ,mybatis和hibernet版本mybatis版本hibernet 版本

public class dynamicdatasource extends abstractroutingdatasource{  

    @override  

    protected object determinecurrentlookupkey() {  

        return dbcontextholder.getdbtype();  

    }  

}  

   上下文dbcontextholder為一線程安全的threadlocal,具體代碼如下:

spring 多資料源 ,mybatis和hibernet版本mybatis版本hibernet 版本

public class dbcontextholder{  

    public static final string data_source_from = "datasourcefrom";  

    public static final string data_source_to = "datasourceto";  

    private static final threadlocal<string> contextholder = new threadlocal<string>();  

    public static void setdbtype(string dbtype) {  

        contextholder.set(dbtype);  

    public static string getdbtype() {  

        return contextholder.get();  

    public static void cleardbtype() {  

        contextholder.remove();  

    3.配置動态資料源

 将dynamicdatasource bean加入到spring的上下文xml配置檔案中去,同時配置dynamicdatasource的targetdatasources(多資料源目标)屬性的map映射。

spring 多資料源 ,mybatis和hibernet版本mybatis版本hibernet 版本

<bean id="dynamicdatasource" class="datasource.dynamicdatasource" >  

    <!-- 通過key-value的形式來關聯資料源 -->  

    <property name="targetdatasources">  

        <map>  

            <entry value-ref="datasourcefrom" key="datasourcefrom"></entry>  

            <entry value-ref="datasourceto" key="datasourceto"></entry>  

        </map>  

    </property>  

    <property name="defaulttargetdatasource" ref="datasourcefrom" />  

</bean>   

    4.使用動态資料源

    例子中dynamicdatasource是繼承與abstractroutingdatasource,而abstractroutingdatasource又是繼承于org.springframework.jdbc.datasource.abstractdatasource,abstractdatasource實作了統一的datasource接口,是以dynamicdatasource同樣可以當一個datasource使用。

 在spring的jdbctemplate使用動态資料源的配置示例:

spring 多資料源 ,mybatis和hibernet版本mybatis版本hibernet 版本

<!-- jdbctemplate使用動态資料源的配置 -->  

<bean id="jdbctemplate" class="org.springframework.jdbc.core.jdbctemplate">  

    <property name="datasource">  

        <ref bean="dynamicdatasource" />  

<!-- 對jdbctemplate的應用封裝類 -->  

<bean id="sqlbasedao" class="com.whty.dao.basedaoimpl">  

    <property name="jdbctemplate">  

        <ref bean="jdbctemplate" />  

spring 多資料源 ,mybatis和hibernet版本mybatis版本hibernet 版本

<bean id="sessionfactory" class="org.springframework.orm.hibernate3.annotation.annotationsessionfactorybean">  

    <!-- 和普通的datasource用法一樣 -->  

    <property name="datasource" ref="dynamicdatasource" />  

    <property name="configlocations" value="classpath:hibernate.cfg.xml" />  

    <property name="hibernateproperties">  

        <props>  

            <prop key="hibernate.dialect">${hibernate.dialect}</prop>     

    5.事務管理

使用動态資料源的時候,可以看出和使用單資料源的時候相比,在使用配置上幾乎沒有差别,在進行性事務管理配置的時候也沒有差别:

使用spring的jdbctemplate的事務管理配置示例:

spring 多資料源 ,mybatis和hibernet版本mybatis版本hibernet 版本

<bean id="transactionmanager" class="org.springframework.jdbc.datasource.datasourcetransactionmanager">  

<bean id="sqlbasedaoproxy" class="org.springframework.transaction.interceptor.transactionproxyfactorybean">  

    <property name="transactionmanager" ref="transactionmanager" />  

    <property name="target" ref="sqlbasedao" />  

    <property name="transactionattributes">  

            <prop key="insert*">propagation_required</prop>  

            <prop key="*">propagation_required,readonly</prop>  

        </props>  

使用hibernate時的事務管理配置示例:

spring 多資料源 ,mybatis和hibernet版本mybatis版本hibernet 版本

<tx:annotation-driven transaction-manager="transactionmanager"/>  

<bean id="transactionmanager" class="org.springframework.orm.hibernate3.hibernatetransactionmanager">  

    <property name="sessionfactory" ref="sessionfactory" />  

    6.動态資料源的管理控制

如何選擇控制每個業務中需要的具體資料源,可是使用手動控制:

spring 多資料源 ,mybatis和hibernet版本mybatis版本hibernet 版本

applicationcontext context = new classpathxmlapplicationcontext("applicationcontext.xml");  

basedao dao = (basedao) context.getbean("sqlbasedao", basedaoimpl.class);  

try {  

    dbcontextholder.setcustomertype(dbcontextholder.data_source_from);  

    system.err.println(dao.select("select count(*) sum from test t ").get(0).get("sum"));  

    dbcontextholder.setcustomertype(dbcontextholder.data_source_to);  

} catch (exception e) {  

    e.printstacktrace();  

也可以采用aop的控制方式:

spring 多資料源 ,mybatis和hibernet版本mybatis版本hibernet 版本

@aspect  

public class dynamicdatasourceaspect {  

    @pointcut("execution (public service.impl..*.*(..))")  

    public void serviceexecution(){}  

    @before("serviceexecution()")  

    public void setdynamicdatasource(joinpoint jp) {  

        for(object o : jp.getargs()) {  

            //處理具體的邏輯 ,根據具體的境況customercontextholder.setcustomertype()選取datasource  

        }  

  7.總結

   通過擴充spring的abstractroutingdatasource可以很好的實作多資料源的rout效果,而且對擴充更多的資料源有良好的伸縮性,隻要增加資料源和修改dynamicdatasource的targetdatasources屬性配置就好。在資料源選擇控制上,可以采用手動控制(業務邏輯并不多的時候),也可以很好的用aop的@aspect在service的入口加入一個切面@pointcut,在@before裡判斷joinpoint的類容標明特定的資料源。

spring 多資料源 ,mybatis和hibernet版本mybatis版本hibernet 版本
spring 多資料源 ,mybatis和hibernet版本mybatis版本hibernet 版本
spring 多資料源 ,mybatis和hibernet版本mybatis版本hibernet 版本
spring 多資料源 ,mybatis和hibernet版本mybatis版本hibernet 版本
spring 多資料源 ,mybatis和hibernet版本mybatis版本hibernet 版本
spring 多資料源 ,mybatis和hibernet版本mybatis版本hibernet 版本
spring 多資料源 ,mybatis和hibernet版本mybatis版本hibernet 版本
spring 多資料源 ,mybatis和hibernet版本mybatis版本hibernet 版本