spring4+mybatis3多数据源配置


使用springAOP方式进行数据源的切换。

细节见配置:

DataSourceAspect.java
import  java.lang.reflect.Method;
import  org.springframework.aop.AfterReturningAdvice;
import  org.springframework.aop.MethodBeforeAdvice;
import  com.stech.system.annotation.DataSource;
import  com.stech.system.config.DataSourceHolder;
public   class  DataSourceAspect  implements  MethodBeforeAdvice, AfterReturningAdvice {
      @Override
      public   void  afterReturning(Object  returnValue , Method  method , Object[]  args , Object  target throws  Throwable {
           DataSourceHolder.clearDataSourceType();
     }
      @Override
      public   void  before(Method  method , Object[]  args , Object  target throws  Throwable {
            if  ( method .isAnnotationPresent( DataSource . class )) {
                 DataSource   datasource  =  method .getAnnotation( DataSource . class );
                DataSourceHolder.setDataSourceType( datasource .value());
           }
     }
}

DataSourceHolder.java
public   class  DataSourceHolder {
     
     private   static   final  ThreadLocal<String>  contextHolder  =  new  ThreadLocal<String>(); 
     /**
     *  @Description : 设置数据源类型
     *  @param  dataSourceType  数据库类型
     *  @return  void
     *  @throws
     */  
     public   static   void  setDataSourceType(String  dataSourceType ) { 
         contextHolder .set( dataSourceType ); 
    } 
     
     /**
     *  @Description : 获取数据源类型
     *  @param  
     *  @return  String
     *  @throws
     */  
     public   static  String getDataSourceType() { 
         return   contextHolder .get(); 
    } 
     
     /**
     *  @Description : 清除数据源类型
     *  @param  
     *  @return  void
     *  @throws
     */  
     public   static   void  clearDataSourceType() { 
         contextHolder .remove(); 
    }

RoutingDataSource.java
import  org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
public   class  RoutingDataSource  extends  AbstractRoutingDataSource  {
      @Override
      protected  Object determineCurrentLookupKey() {
             return  DataSourceHolder.getDataSourceType();
     }
}

DataSource.java
import  java.lang.annotation.ElementType;
import  java.lang.annotation.Retention;
import  java.lang.annotation.RetentionPolicy;
import  java.lang.annotation.Target;
/**
 * 数据源
 *  @author  jiangnan
 **  @see  com.stech.system.interceptor.DataSourceAspect
 */
@Target (ElementType. METHOD )
@Retention (RetentionPolicy. RUNTIME )
public   @interface   DataSource  {
     String value()  default   "" ;
}


spring-config-multidatasource.xml
<? xml   version = "1.0"   encoding = "UTF-8" ?>
< beans   xmlns = "http://www.springframework.org/schema/beans"
      xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation = "
           http://www.springframework.org/schema/beans
          http://www.springframework.org/schema/beans/spring-beans-4.1.xsd" >
      <!-- 数据源druid的配置 -->
      < bean   id = "parentDataSource"   class = "com.alibaba.druid.pool.DruidDataSource"
            init-method = "init"   destroy-method = "close" >
            <!-- 基本属性 url、user、password -->
            < property   name = "url"   value = "${connection1.url}"   />
            < property   name = "username"   value = "${connection1.username}"   />
            < property   name = "password"   value = "${connection1.password}"   />
            <!-- 配置初始化大小、最小、最大 -->
            < property   name = "initialSize"   value = "${druid.initialSize}"   />
            < property   name = "minIdle"   value = "${druid.minIdle}"   />
            < property   name = "maxActive"   value = "${druid.maxActive}"   />
            <!-- 配置获取连接等待超时的时间 -->
            < property   name = "maxWait"   value = "${druid.maxWait}"   />
            <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
            < property   name = "timeBetweenEvictionRunsMillis"   value = "${druid.timeBetweenEvictionRunsMillis}"   />
            <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
            < property   name = "minEvictableIdleTimeMillis"   value = "${druid.minEvictableIdleTimeMillis}"   />
            < property   name = "validationQuery"   value = "${druid.validationQuery}"   />
            < property   name = "testWhileIdle"   value = "${druid.testWhileIdle}"   />
            < property   name = "testOnBorrow"   value = "${druid.testOnBorrow}"   />
            < property   name = "testOnReturn"   value = "${druid.testOnReturn}"   />
            <!-- 打开PSCache,并且指定每个连接上PSCache的大小 如果用Oracle,则把poolPreparedStatements配置为true,mysql可以配置为false。 -->
            < property   name = "poolPreparedStatements"   value = "${druid.poolPreparedStatements}"   />
            < property   name = "maxPoolPreparedStatementPerConnectionSize"
                value = "${druid.maxPoolPreparedStatementPerConnectionSize}"   />
            <!-- 配置监控统计拦截的filters -->
            < property   name = "filters"   value = "${druid.filters}"   />
      </ bean >
      < bean   id = "dataSource1"   parent = "parentDataSource" >
            < property   name = "url"   value = "${connection1.url}"   />
            < property   name = "username"   value = "${connection1.username}"   />
            < property   name = "password"   value = "${connection1.password}"   />
      </ bean >
      < bean   id = "dataSource2"   parent = "parentDataSource" >
            < property   name = "url"   value = "${connection2.url}"   />
            < property   name = "username"   value = "${connection2.username}"   />
            < property   name = "password"   value = "${connection2.password}"   />
      </ bean >
   <!-- method 1:  config switch routing db -->
     < bean   id = "dataSource"   class = "com.stech.system.config.RoutingDataSource" >
         < property   name = "targetDataSources" >
             < map   key-type = "java.lang.String" >
                 < entry   key = "${jdbc-key-1}"   value-ref = "dataSource1" />
                 < entry   key = "${jdbc-key-2}"   value-ref = "dataSource2" />
             </ map >
         </ property >
          < property   name = "defaultTargetDataSource"   ref = "dataSource1" />
     </ bean >
</ beans >

spring-config-tx.xml
<? 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:tx = "http://www.springframework.org/schema/tx"
      xmlns:context = "http://www.springframework.org/schema/context"
      xmlns:aop = "http://www.springframework.org/schema/aop"
      xmlns:task = "http://www.springframework.org/schema/task"
      xsi:schemaLocation = "
           http://www.springframework.org/schema/beans
          http://www.springframework.org/schema/beans/spring-beans.xsd
           http://www.springframework.org/schema/tx
          http://www.springframework.org/schema/tx/spring-tx.xsd
           http://www.springframework.org/schema/context
          http://www.springframework.org/schema/context/spring-context.xsd
           http://www.springframework.org/schema/aop
          http://www.springframework.org/schema/aop/spring-aop.xsd
           http://www.springframework.org/schema/task
          http://www.springframework.org/schema/task/spring-task-4.1.xsd"
      default-lazy-init = "false" >
     
      <!-- 声明式事务管理 -->
      < bean   id = "transactionManager"   class = "org.springframework.jdbc.datasource.DataSourceTransactionManager" >
            < property   name = "dataSource"   ref = "dataSource"   />
      </ bean >
     
      <!--  配置事务传播特性 isolation="READ_COMMITTED" -->
      < tx:advice   id = "userTxAdvice"   transaction-manager = "transactionManager" >
            < tx:attributes >
                 < tx:method   name = "insert*"   propagation = "REQUIRED"   read-only = "false"    rollback-for = "java.lang.Exception"   />
                 < tx:method   name = "save*"   propagation = "REQUIRED"   read-only = "false"      rollback-for = "java.lang.Exception"   />
                 < tx:method   name = "add*"   propagation = "REQUIRED"   read-only = "false"      rollback-for = "java.lang.Exception"   />
                 < tx:method   name = "update*"   propagation = "REQUIRED"   read-only = "false"      rollback-for = "java.lang.Exception"   />
                 < tx:method   name = "delete*"   propagation = "REQUIRED"   read-only = "false"    rollback-for = "java.lang.Exception"   />
                 < tx:method   name = "remove*"   propagation = "REQUIRED"   read-only = "false"    rollback-for = "java.lang.Exception"   />
                 < tx:method   name = "*"   read-only = "true"   rollback-for = "java.lang.Exception"   />
            </ tx:attributes >
      </ tx:advice >
     
      < bean  id = "dataSourceAspect"   class = "com.stech.system.interceptor.DataSourceAspect" ></ bean >
      <!--  配置参与事务的类 -->
      < aop:config   expose-proxy = "true"   proxy-target-class = "true" >
            < aop:pointcut   id = "pc"   expression = "execution(* com.*.*.service.*.*.*(..))"   />
            < aop:advisor   pointcut-ref = "pc"   advice-ref = "userTxAdvice"   order = "2" />
            < aop:advisor   pointcut-ref = "pc"   advice-ref = "dataSourceAspect"   order = "1" />
      </ aop:config >
     
      < tx:annotation-driven   proxy-target-class = "true"   transaction-manager = "transactionManager" />


#database configuration
jdbc.type= mysql
jdbc-key-1= stuaffairs
connection1.url= jdbc:mysql://localhost:3306/stuaffairs?useUnicode=true&characterEncoding=utf8
connection1.username= root
connection1.password=
jdbc-key-2= datacenter
connection2.url= jdbc:mysql://localhost:3306/datacenter?useUnicode=true&characterEncoding=utf8
connection2.username= root
connection2.password=
#druid
druid.initialSize= 10
druid.minIdle= 10
druid.maxActive= 50
druid.maxWait= 60000
druid.timeBetweenEvictionRunsMillis= 60000
druid.minEvictableIdleTimeMillis= 300000
druid.validationQuery= SELECT   'x'
druid.testWhileIdle= true
druid.testOnBorrow= false
druid.testOnReturn= false
druid.poolPreparedStatements= true
druid.maxPoolPreparedStatementPerConnectionSize= 20
druid.filters= wall,stat

测试通过。 利用在service的method上的注解,进行数据源的切换,同时增加了数据库的事务。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值