天天看点

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 版本