mybatisAOP多数据源配置(使用阿里数据库连接池)

由于项目中需要使用数据源,用的网上开源的项目,之前使用网上通用的多数据源配置,没有切换成功,于是采用了AOP来切换数据源。

(此处只贴出关于多数据源和其他部分的一些配置)

spring-context.xml

  1 <?xml version="1.0" encoding="UTF-8"?>
  2 <beans xmlns="http://www.springframework.org/schema/beans" 
  3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4     xmlns:context="http://www.springframework.org/schema/context" 
  5     xmlns:jdbc="http://www.springframework.org/schema/jdbc"  
  6     xmlns:aop="http://www.springframework.org/schema/aop" 
  7     xmlns:jee="http://www.springframework.org/schema/jee" 
  8     xmlns:tx="http://www.springframework.org/schema/tx"
  9     xmlns:util="http://www.springframework.org/schema/util"
 10     xmlns:task="http://www.springframework.org/schema/task" 
 11     xsi:schemaLocation="
 12         http://www.springframework.org/schema/beans 
 13         http://www.springframework.org/schema/beans/spring-beans-4.1.xsd 
 14         http://www.springframework.org/schema/context 
 15         http://www.springframework.org/schema/context/spring-context-4.1.xsd 
 16         http://www.springframework.org/schema/jdbc 
 17         http://www.springframework.org/schema/jdbc/spring-jdbc-4.1.xsd 
 18         http://www.springframework.org/schema/aop 
 19          http://www.springframework.org/schema/aop/spring-aop.xsd 
 20         http://www.springframework.org/schema/jee 
 21         http://www.springframework.org/schema/jee/spring-jee-4.1.xsd 
 22         http://www.springframework.org/schema/lang 
 23          http://www.springframework.org/schema/lang/spring-lang.xsd 
 24         http://www.springframework.org/schema/tx 
 25         http://www.springframework.org/schema/tx/spring-tx-4.1.xsd 
 26         http://www.springframework.org/schema/util 
 27         http://www.springframework.org/schema/util/spring-util-4.1.xsd 
 28         http://www.springframework.org/schema/task 
 29         http://www.springframework.org/schema/task/spring-task-4.1.xsd"
 30     default-lazy-init="true">
 31 
 32     <description>Spring Configuration</description>
 33     
 34     <!-- 加载配置属性文件 -->
 35     <context:property-placeholder ignore-unresolvable="true" location="classpath:jeesite.properties" />
 36     
 37     <!-- 加载应用属性实例,可通过  @Value("#{APP_PROP['jdbc.driver']}") String jdbcDriver 方式引用 -->
 38     <util:properties id="APP_PROP" location="classpath:jeesite.properties" local-override="true"/>
 39     
 40     <!-- 使用Annotation自动注册Bean,解决事物失效问题:在主容器中不扫描@Controller注解,在SpringMvc中只扫描@Controller注解。  -->
 41     <context:component-scan base-package="com.vcard"><!-- base-package 如果多个,用“,”分隔 -->
 42         <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
 43     </context:component-scan>
 44     
 45     <bean id="jedisUtil" class="h2o.common.thirdparty.redis.JedisUtil">
 46         <constructor-arg>
 47             <list>
 48                 <value>localhost:6379</value>
 49                 <value>localhost:6379</value>
 50             </list>
 51         </constructor-arg>
 52     </bean>
 53     
 54      <!-- MyBatis begin -->
 55     <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
 56         <!-- <property name="dataSource" ref="dataSource"/> -->
 57         <property name="dataSource" ref="dynamicDataSource"/>
 58         <property name="typeAliasesPackage" value="com.vcard"/>
 59         <property name="typeAliasesSuperType" value="com.vcard.common.persistence.BaseEntity"/>
 60         <property name="mapperLocations" value="classpath:/mappings/**/*.xml"/>
 61         <property name="configLocation" value="classpath:/mybatis-config.xml"></property>
 62     </bean>
 63     
 64     <!-- 扫描basePackage下所有以@MyBatisDao注解的接口 -->
 65     <bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
 66         <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
 67         <property name="basePackage" value="com.vcard"/>
 68         <property name="annotationClass" value="com.vcard.common.persistence.annotation.MyBatisDao"/>
 69     </bean>
 70     
 71     <!-- 动态数据源 -->
 72     <bean id="dynamicDataSource" class="com.vcard.common.db.DynamicDataSource">
 73          <property name="defaultTargetDataSource" ref="dataSource"/>
 74          <property name="targetDataSources">
 75              <map key-type="java.lang.String">
 76                  <!-- <entry key="dataSource" value-ref="dataSource"/> -->
 77                  <entry key="dataSource2" value-ref="dataSource2"/>
 78              </map>
 79          </property>
 80     </bean>
 81     
 82      <!-- 定义事务 -->
 83     <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
 84         <property name="dataSource" ref="dynamicDataSource" />
 85     </bean>
 86     
 87     <!-- 配置 Annotation 驱动,扫描@Transactional注解的类定义事务  -->
 88     <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
 89     
 90     <!-- 拦截器方式配置事务 -->
 91     <tx:advice id="transactionAdvice" transaction-manager="transactionManager">
 92         <tx:attributes>
 93             <tx:method name="get*" propagation="REQUIRED" read-only="true"/>
 94             <tx:method name="find*" propagation="REQUIRED" read-only="true"/>
 95             <tx:method name="list*" propagation="REQUIRED" read-only="true"/>
 96             <tx:method name="insert*" rollback-for="java.lang.Exception" propagation="REQUIRED" read-only="false"/>
 97             <tx:method name="create*" rollback-for="java.lang.Exception" propagation="REQUIRED" read-only="false"/>
 98             <tx:method name="update*" rollback-for="java.lang.Exception" propagation="REQUIRED" read-only="false"/>
 99             <tx:method name="save*" rollback-for="java.lang.Exception" propagation="REQUIRED" read-only="false"/>
100             <tx:method name="delete*" rollback-for="java.lang.Exception" propagation="REQUIRED" read-only="false"/>
101             <tx:method name="upd*" rollback-for="java.lang.Exception" propagation="REQUIRED" read-only="false"/>
102         </tx:attributes>
103     </tx:advice>
104     
105     <bean id="transactionAdvice" class="com.vcard.common.db.DataSourceAspect"></bean>
106     
107     <aop:config>
108         <aop:pointcut id="transactionPointcut" expression="execution(* com.vcard.second.modules.order.web.*.*(..))" />
109         <aop:advisor advice-ref="transactionAdvice" pointcut-ref="transactionPointcut"/>
110     </aop:config>
111     
112     <!-- 定义事务 -->
113     <!-- <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
114         <property name="dataSource" ref="dataSource" />
115     </bean> -->
116     <!-- MyBatis end -->
117     
118     <!-- 配置 JSR303 Bean Validator 定义 -->
119     <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />
120 
121     <!-- 缓存配置 -->
122     <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
123         <property name="configLocation" value="classpath:${ehcache.configFile}" />
124     </bean>
125     
126     <!-- 计划任务配置,用 @Service @Lazy(false)标注类,用@Scheduled(cron = "0 0 2 * * ?")标注方法 -->
127     <task:executor id="executor" pool-size="10"/> <task:scheduler id="scheduler" pool-size="10"/>
128     <task:annotation-driven scheduler="scheduler" executor="executor" proxy-target-class="true"/>
129     
130     <!-- 数据源配置, 使用 BoneCP 数据库连接池 -->
131     <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"> 
132         <!-- 数据源驱动类可不写,Druid默认会自动根据URL识别DriverClass -->
133         <property name="driverClassName" value="${jdbc.driver}" />
134         
135         <!-- 基本属性 url、user、password -->
136         <property name="url" value="${jdbc.url}" />
137         <property name="username" value="${jdbc.username}" />
138         <property name="password" value="${jdbc.password}" />
139         
140         <!-- 配置初始化大小、最小、最大 -->
141         <property name="initialSize" value="${jdbc.pool.init}" />
142         <property name="minIdle" value="${jdbc.pool.minIdle}" /> 
143         <property name="maxActive" value="${jdbc.pool.maxActive}" />
144         
145         <!-- 配置获取连接等待超时的时间 -->
146         <property name="maxWait" value="60000" />
147         
148         <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
149         <property name="timeBetweenEvictionRunsMillis" value="60000" />
150         
151         <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
152         <property name="minEvictableIdleTimeMillis" value="300000" />
153         
154         <property name="validationQuery" value="${jdbc.testSql}" />
155         <property name="testWhileIdle" value="true" />
156         <property name="testOnBorrow" value="false" />
157         <property name="testOnReturn" value="false" />
158         
159         <!-- 打开PSCache,并且指定每个连接上PSCache的大小(Oracle使用)
160         <property name="poolPreparedStatements" value="true" />
161         <property name="maxPoolPreparedStatementPerConnectionSize" value="20" /> -->
162         
163         <!-- 配置监控统计拦截的filters -->
164         <property name="filters" value="stat" /> 
165     </bean>
166     
167     <!-- 数据源配置, 使用 BoneCP 数据库连接池 -->
168     <bean id="dataSource2" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"> 
169         <!-- 数据源驱动类可不写,Druid默认会自动根据URL识别DriverClass -->
170         <property name="driverClassName" value="${jdbc2.driver}" />
171         
172         <!-- 基本属性 url、user、password -->
173         <property name="url" value="${jdbc2.url}" />
174         <property name="username" value="${jdbc2.username}" />
175         <property name="password" value="${jdbc2.password}" />
176         
177         <!-- 配置初始化大小、最小、最大 -->
178         <property name="initialSize" value="${jdbc2.pool.init}" />
179         <property name="minIdle" value="${jdbc2.pool.minIdle}" /> 
180         <property name="maxActive" value="${jdbc2.pool.maxActive}" />
181         
182         <!-- 配置获取连接等待超时的时间 -->
183         <property name="maxWait" value="60000" />
184         
185         <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
186         <property name="timeBetweenEvictionRunsMillis" value="60000" />
187         
188         <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
189         <property name="minEvictableIdleTimeMillis" value="300000" />
190         
191         <property name="validationQuery" value="${jdbc.testSql}" />
192         <property name="testWhileIdle" value="true" />
193         <property name="testOnBorrow" value="false" />
194         <property name="testOnReturn" value="false" />
195         
196         <!-- 打开PSCache,并且指定每个连接上PSCache的大小(Oracle使用)
197         <property name="poolPreparedStatements" value="true" />
198         <property name="maxPoolPreparedStatementPerConnectionSize" value="20" /> -->
199         
200         <!-- 配置监控统计拦截的filters -->
201         <property name="filters" value="stat" /> 
202     </bean>
203 
204     <!-- 数据源配置, 使用应用服务器的数据库连接池 
205     <jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/jeesite" />-->
206 
207     <!-- 数据源配置, 不使用连接池 
208     <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
209         <property name="driverClassName" value="${jdbc.driver}" />
210         <property name="url" value="${jdbc.url}" />
211         <property name="username" value="${jdbc.username}"/>
212         <property name="password" value="${jdbc.password}"/>
213     </bean>-->
214     
215 </beans>

jeesite.properties

  1 #============================#
  2 #===== Database sttings =====#
  3 #============================#
  4 
  5 #oracle database settings
  6 #jdbc.type=oracle
  7 #jdbc.driver=oracle.jdbc.driver.OracleDriver
  8 #jdbc.url=jdbc:oracle:thin:@127.0.0.1:1521:orcl
  9 #jdbc.username=jeesite
 10 #jdbc.password=123456
 11 
 12 #mysql database setting
 13 jdbc.type=mysql
 14 jdbc.driver=com.mysql.jdbc.Driver
 15 #jdbc.url=jdbc:mysql://localhost:3306/vcardjeesite?useUnicode=true&characterEncoding=utf-8
 16 #jdbc.username=root
 17 #jdbc.password=123456
 18 jdbc.url=jdbc:mysql://localhost:3306/vcardjeesite?useUnicode=true&characterEncoding=utf-8
 19 jdbc.username=changyue
 20 jdbc.password=cykjdev164123
 21 
 22 jdbc2.type=mysql
 23 jdbc2.driver=com.mysql.jdbc.Driver
 24 jdbc2.url=jdbc:mysql://localhost:3306/newmall?useUnicode=true&characterEncoding=utf-8
 25 jdbc2.username=changyue
 26 jdbc2.password=cykjdev164123
 27 #jdbc2.url=jdbc:mysql://localhost:3306/newmalljeesite?useUnicode=true&characterEncoding=utf-8
 28 #jdbc2.username=root
 29 #jdbc2.password=123456
 30 
 31 #mssql database settings
 32 #jdbc.type=mssql
 33 #jdbc.driver=net.sourceforge.jtds.jdbc.Driver
 34 #jdbc.url=jdbc:jtds:sqlserver://localhost:1433/jeesite
 35 #jdbc.username=sa
 36 #jdbc.password=sa
 37 
 38 #pool settings
 39 jdbc.pool.init=1
 40 jdbc.pool.minIdle=3
 41 jdbc.pool.maxActive=20
 42 
 43 jdbc2.pool.init=1
 44 jdbc2.pool.minIdle=3
 45 jdbc2.pool.maxActive=20
 46 
 47 #jdbc.testSql=SELECT 'x'
 48 jdbc.testSql=SELECT 'x' FROM DUAL
 49 
 50 #redis settings
 51 redis.keyPrefix=vcard
 52 redis.host=localhost
 53 redis.port=6379
 54 
 55 #============================#
 56 #===== System settings ======#
 57 #============================#
 58 
 59 #\u4ea7\u54c1\u4fe1\u606f\u8bbe\u7f6e
 60 productName=\u5546\u6237\u5F00\u653E\u5E73\u53F0
 61 copyrightYear=2017
 62 version=V1.2.7
 63 
 64 #\u6f14\u793a\u6a21\u5f0f: \u4e0d\u80fd\u64cd\u4f5c\u548c\u4fdd\u5b58\u7684\u6a21\u5757\uff1a sys: area/office/user/role/menu/dict, cms: site/category
 65 demoMode=false
 66 
 67 #\u7ba1\u7406\u57fa\u7840\u8def\u5f84, \u9700\u540c\u6b65\u4fee\u6539\uff1aweb.xml
 68 adminPath=/a
 69 
 70 #\u524d\u7aef\u57fa\u7840\u8def\u5f84
 71 frontPath=/f
 72 
 73 #\u7f51\u7ad9URL\u540e\u7f00
 74 urlSuffix=.html
 75 
 76 #\u662f\u5426\u4e0d\u5141\u8bb8\u5237\u65b0\u4e3b\u9875\uff0c\u4e0d\u5141\u8bb8\u60c5\u51b5\u4e0b\uff0c\u5237\u65b0\u4e3b\u9875\u4f1a\u5bfc\u81f4\u91cd\u65b0\u767b\u5f55
 77 notAllowRefreshIndex=false
 78 
 79 #\u662f\u5426\u5141\u8bb8\u591a\u8d26\u53f7\u540c\u65f6\u767b\u5f55
 80 user.multiAccountLogin=true
 81 
 82 #\u5206\u9875\u914d\u7f6e
 83 page.pageSize=10
 84 
 85 #\u7855\u6b63\u7ec4\u4ef6\u662f\u5426\u4f7f\u7528\u7f13\u5b58
 86 supcan.useCache=false
 87 
 88 #\u901a\u77e5\u95f4\u9694\u65f6\u95f4\u8bbe\u7f6e, \u5355\u4f4d\uff1a\u6beb\u79d2, 30s=30000ms, 60s=60000ms
 89 oa.notify.remind.interval=60000
 90 
 91 #============================#
 92 #==== Framework settings ====#
 93 #============================#
 94 
 95 #\u4f1a\u8bdd\u8d85\u65f6\uff0c \u5355\u4f4d\uff1a\u6beb\u79d2\uff0c 20m=1200000ms, 30m=1800000ms, 60m=3600000ms
 96 session.sessionTimeout=1800000
 97 #\u4f1a\u8bdd\u6e05\u7406\u95f4\u9694\u65f6\u95f4\uff0c \u5355\u4f4d\uff1a\u6beb\u79d2\uff0c2m=120000ms\u3002
 98 session.sessionTimeoutClean=120000
 99 
100 #\u7f13\u5b58\u8bbe\u7f6e
101 ehcache.configFile=cache/ehcache-local.xml
102 #ehcache.configFile=cache/ehcache-rmi.xml
103 
104 #\u7d22\u5f15\u9875\u8def\u5f84
105 web.view.index=/a
106 
107 #\u89c6\u56fe\u6587\u4ef6\u5b58\u653e\u8def\u5f84
108 web.view.prefix=/WEB-INF/views/
109 web.view.suffix=.jsp
110 
111 #\u6700\u5927\u6587\u4ef6\u4e0a\u4f20\u9650\u5236\uff0c\u5355\u4f4d\u5b57\u8282. 10M=10*1024*1024(B)=10485760 bytes\uff0c\u9700\u540c\u6b65\u4fee\u6539\uff1ackfinder.xml
112 web.maxUploadSize=10485760
113 
114 #\u65e5\u5fd7\u62e6\u622a\u8bbe\u7f6e\uff0c\u6392\u9664\u7684URI\uff1b\u5305\u542b @RequestMapping\u6ce8\u89e3\u7684value\u3002\uff08\u5df2\u4f5c\u5e9f\uff09
115 #web.logInterceptExcludeUri=/, /login, /sys/menu/tree, /sys/menu/treeData, /oa/oaNotify/self/count
116 #web.logInterceptIncludeRequestMapping=save, delete, import, updateSort
117 
118 #\u9759\u6001\u6587\u4ef6\u540e\u7f00
119 web.staticFile=.css,.js,.png,.jpg,.gif,.jpeg,.bmp,.ico,.swf,.psd,.htc,.htm,.html,.crx,.xpi,.exe,.ipa,.apk
120 
121 #\u5355\u70b9\u767b\u5f55CAS\u8bbe\u7f6e
122 cas.server.url=http://127.0.0.1:8080/cas
123 cas.project.url=http://127.0.0.1:8080/vcard
124 
125 #\u5de5\u4f5c\u6d41\u8bbe\u7f6e
126 activiti.isSynActivitiIndetity=false
127 activiti.export.diagram.path=c:/activiti_diagram
128 #activiti font (windows font: \u5b8b\u4f53  linux font: simsun)
129 activiti.diagram.activityFontName=\u5b8b\u4f53
130 activiti.diagram.labelFontName=\u5b8b\u4f53
131 #5.21.0 \u65b0\u589e\u53c2\u6570 ,2016.06.23 \u8f66\u6811\u708e add
132 activiti.diagram.annotationFontName=\u5b8b\u4f53
133 #activiti\u5916\u90e8\u8868\u5355\u6839\u5730\u5740\u914d\u7f6e
134 activiti.form.server.url=
135 
136 #\u4e0a\u4f20\u6587\u4ef6\u7edd\u5bf9\u8def\u5f84, \u8def\u5f84\u4e2d\u4e0d\u5141\u8bb8\u5305\u542b\u201cuserfiles\u201d
137 #userfiles.basedir=D:/jeesite
138 
139 #\u5de5\u7a0b\u8def\u5f84\uff0c\u5728\u4ee3\u7801\u751f\u6210\u65f6\u83b7\u53d6\u4e0d\u5230\u5de5\u7a0b\u8def\u5f84\u65f6\uff0c\u53ef\u518d\u6b64\u6307\u5b9a\u7edd\u5bf9\u8def\u5f84\u3002
140 #projectPath=D\:\\workspace\\jeesite

DynamicDataSource.java

 1 import org.aspectj.lang.annotation.Aspect;
 2 import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
 3 import org.springframework.stereotype.Component;
 4 
 5 /**
 6  * 多数据源配置
 7  */
 8 @Component
 9 @Aspect
10 public class DynamicDataSource extends AbstractRoutingDataSource {
11 
12     public DynamicDataSource() {
13     }
14     
15     @Override
16     protected Object determineCurrentLookupKey() {
17         return DBContextHolder.getDbType();
18     }
19     
20     public java.util.logging.Logger getParentLogger() {
21         return null;
22     }
23 }

DBContextHolder.java

 1 public class DBContextHolder {
 2     private static ThreadLocal<String> contextHolder = new ThreadLocal<String>();
 3     public static String Master = "dataSource";
 4     public static String Slave = "dataSource2";
 5     
 6     public DBContextHolder() {
 7     }
 8 
 9     public static String getDbType() {
10         String db = contextHolder.get();
11         if (db == null) {
12             db = Master;
13         }
14         return db;
15     }
16     
17     public static void setDbType(String str) {
18         contextHolder.set(str);
19     }
20     
21     public static void setMater() {
22         contextHolder.set(Master);
23     }
24     
25     public static void serSlave() {
26         contextHolder.set(Slave);
27     }
28     
29     public static void clearDBType() {
30         contextHolder.remove();
31     }
32 }

DataSourceAspect.java

 1 import java.lang.reflect.Method;
 2 
 3 import org.apache.logging.log4j.LogManager;
 4 import org.apache.logging.log4j.Logger;
 5 import org.aspectj.lang.JoinPoint;
 6 import org.springframework.aop.AfterReturningAdvice;
 7 import org.springframework.aop.MethodBeforeAdvice;
 8 import org.springframework.aop.ThrowsAdvice;
 9 
10 public class DataSourceAspect implements MethodBeforeAdvice, AfterReturningAdvice, ThrowsAdvice {
11     private static final Logger log = LogManager.getLogger(DataSourceAspect.class);
12 
13     public DataSourceAspect() {
14     }
15 
16     public void before(Method m, Object[] args, Object target) throws Throwable {
17         try {
18             if (m != null) {
19                 // 拦截ImsShopOrderController中的方法,切换数据源
20                 if ((m.getName().equals("listImsShopOrder") 
21                         || m.getName().equals("sendGoods") 
22                         || m.getName().equals("cancleSend")) 
23                         && !m.getName().contains("FromMaster")) {
24                     DBContextHolder.setDbType(DBContextHolder.Slave);
25                 } else {
26                     DBContextHolder.setDbType(DBContextHolder.Master);
27                 }
28             }
29         } catch (Exception var5) {
30             log.error("data source aspect error.", var5);
31         }
32 
33     }
34 
35     public void after(JoinPoint point) {
36         log.info("clear db type after method.current id {}",
37                 new Object[] { Long.valueOf(Thread.currentThread().getId()) });
38         DBContextHolder.clearDBType();
39     }
40 
41     public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
42     }
43 
44     public void afterThrowing(Method method, Object[] args, Object target, Exception ex) throws Throwable {
45         log.info("current db type {} when exception", new Object[] { DBContextHolder.getDbType() });
46         DBContextHolder.setDbType(DBContextHolder.Master);
47     }
48 }

 

posted @ 2018-01-22 11:14  向前爬的蜗牛  阅读(392)  评论(0编辑  收藏  举报