java 多数据源实例

来源:互联网 发布:macbookair怎样装软件 编辑:程序博客网 时间:2024/06/11 03:08

主要需要解决的问题
1,数据源的切换
2,数据源切换aop 必须在 spring事务 aop 之前
3,因为不同数据库都是 mysql , 所以使用不同dataSource,但同一个sessionFactory,(如果是不同的数据库,则需要切换 配置多套dataSource,sessionFactory,然后切换sessionFactory)
4,数据源切换的切面在 service 层,不能再dao 层,因为事务的aop 在service层

一, 配置文件内容

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"    xmlns:p="http://www.springframework.org/schema/p"    xsi:schemaLocation="http://www.springframework.org/schema/beans     http://www.springframework.org/schema/beans/spring-beans-3.2.xsd     http://www.springframework.org/schema/context     http://www.springframework.org/schema/context/spring-context-3.2.xsd     http://www.springframework.org/schema/aop     http://www.springframework.org/schema/aop/spring-aop-3.2.xsd     http://www.springframework.org/schema/tx     http://www.springframework.org/schema/tx/spring-tx-3.2.xsd"    default-autowire="default" default-lazy-init="false">    <context:component-scan base-package="ssh"></context:component-scan>    <!-- 导入配置信息 -->    <context:property-placeholder location="classpath:sshTemplate.properties" />    <!-- 导入其它配置文件 --><!--    <import resource="task.xml" /> -->    <!-- 第一个数据源 -->    <bean id="dataSourceOne" class="com.alibaba.druid.pool.DruidDataSource">        <property name="driverClassName" value="${db.driver.one}" />        <property name="url" value="${db.url.one}" />        <property name="username" value="${db.username.one}" />        <property name="password" value="${db.password.one}" />        <property name="initialSize" value="5"/>        <property name="maxActive" value="100"/>        <property name="maxWait" value="60000"/>        <property name="minIdle" value="5"/>    </bean>    <!-- 第二个数据源 -->    <bean id="dataSourceTwo" class="com.alibaba.druid.pool.DruidDataSource">        <property name="driverClassName" value="${db.driver.two}" />        <property name="url" value="${db.url.two}" />        <property name="username" value="${db.username.two}" />        <property name="password" value="${db.password.two}" />        <property name="initialSize" value="5"/>        <property name="maxActive" value="100"/>        <property name="maxWait" value="60000"/>        <property name="minIdle" value="5"/>    </bean>    <!-- 动态数据源 -->    <bean id="dynamicDataSource" class="ssh.multipleDataSource.DynamicDataSource">          <property name="targetDataSources">              <map key-type="java.lang.String">                  <entry value-ref="dataSourceOne" key="dataSourceOne"></entry>                  <entry value-ref="dataSourceTwo" key="dataSourceTwo"></entry>              </map>          </property>          <property name="defaultTargetDataSource" ref="dataSourceOne">          </property>      </bean>      <!-- sessionFactory -->    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"        lazy-init="false">        <property name="dataSource" ref="dynamicDataSource" />        <property name="packagesToScan">            <list>                <value>ssh.model</value>            </list>        </property>        <property name="hibernateProperties">            <props>                <prop key="hibernate.dialect">                    org.hibernate.dialect.MySQL5InnoDBDialect                </prop>                <prop key="hibernate.show_sql">true</prop>                <prop key="hibernate.format_sql">true</prop>            </props>        </property>    </bean>    <!-- hibernateTemplate -->    <bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate" >        <property name="sessionFactory" ref="sessionFactory"></property>    </bean>    <!-- 定义事务管理器(声明式的事务) -->    <bean id="transactionManager"        class="org.springframework.orm.hibernate3.HibernateTransactionManager">        <property name="sessionFactory" ref="sessionFactory" />    </bean>    <tx:annotation-driven transaction-manager="transactionManager" order="5" /> <!-- 设置order 5,保证在数据源切换之后执行 -->    <!-- 切换数据源 -->    <bean id="dataSourceInterceptor" class="ssh.multipleDataSource.DataSourceInterceptor"></bean>    <aop:config>        <aop:aspect id="dataSourceAspect" ref="dataSourceInterceptor" order="4"><!-- 设置order 4,保护证在 事务之前执行 -->            <aop:pointcut expression="execution(* ssh.service.oneService.*.*(..))" id="oneService"/>            <aop:pointcut expression="execution(* ssh.service.twoService.*.*(..))" id="twoService"/>            <aop:before method="switchDataBaseOne" pointcut-ref="oneService"/>            <aop:before method="switchDataBaseTwo" pointcut-ref="twoService"/>        </aop:aspect>    </aop:config></beans>

其中数据源切换使用的类:

package ssh.multipleDataSource;import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;/** * 动态数据源,继承AbstractRoutingDataSource,并实现determineCurrentLookupKey方法 * @author wwp * */public class DynamicDataSource extends AbstractRoutingDataSource{    @Override    protected Object determineCurrentLookupKey() {        return DataBaseContextHolder.getCustomerType();    }}
package ssh.multipleDataSource;/** * @author wwp *  */public class DataBaseContextHolder {    /**     * 数据源切换类 使用ThreadLocal确保线程安全     */    private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();    public static void setCustomerType(String customerType) {        contextHolder.set(customerType);    }    public static String getCustomerType() {        return contextHolder.get();    }    public static void clearCustomerType() {        contextHolder.remove();    }}
package ssh.multipleDataSource;import org.aspectj.lang.JoinPoint;import org.springframework.stereotype.Component;/** * aop 实现拦截,选择数据源 * @author wwp */@Componentpublic class DataSourceInterceptor {    public void switchDataBaseOne(JoinPoint jp){        System.out.println("选择数据源1");        DataBaseContextHolder.setCustomerType("dataSourceOne");    }    public void switchDataBaseTwo(){        System.out.println("选择数据源2");        DataBaseContextHolder.setCustomerType("dataSourceTwo");    }}

经过测试,可以实现数据源的切换,并且保证事务;

0 0
原创粉丝点击