记录说明:项目使用Spring+SpringMVC+Mybatis框架,项目之前一直在使用mysql数据库,后因项目对接需要,配置多数据源增加sqlserver数据库。
梳理一下相关的文件:
1、pom.xml文件(使用的是maven管理工具)
2、DataSource 接口注解文件
3、DataSourceAspect 类文件
4、DynamicDataSourceHolder 类文件
5、MultipleDataSource 类文件
6、jdbc.properties 配置文件
7、spring-mybatis.xml 配置文件
以上文件缺一不可!!

pom.xml文件增加依赖jar
<dependency> <groupId>net.sourceforge.jtds</groupId> <artifactId>jtds</
artifactId> <version>1.2.4</version> </dependency> <dependency> <groupId>
com.microsoft.sqlserver</groupId> <artifactId>sqljdbc4</artifactId> <version>2.0
</version> </dependency>
jar包下载:https://download.csdn.net/download/qq_35393472/10671922
<https://download.csdn.net/download/qq_35393472/10671922>

DataSource 接口注解文件
import java.lang.annotation.Documented; import
java.lang.annotation.ElementType;import java.lang.annotation.Retention; import
java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target; /** *
此处用于定义DataSource注解,通过注解的方式指定需要访问的数据源 * @author:lujingyu * @data
:2018年9月17日下午2:10:54 */ @Documented @Target({ElementType.TYPE,
ElementType.METHOD})@Retention(RetentionPolicy.RUNTIME) public @interface
DataSource { String value(); }
DataSourceAspect 类文件
import java.lang.reflect.Method; import org.aspectj.lang.JoinPoint; import
org.aspectj.lang.reflect.MethodSignature;public class DataSourceAspect { /** *
拦截目标方法,获取由@DataSource指定的数据源标识,设置到线程存储中以便切换数据源 * * @param point * @throws
Exception */ public void intercept(JoinPoint point) throws Exception { Class<?>
target = point.getTarget().getClass(); MethodSignature signature =
(MethodSignature) point.getSignature();// 默认使用目标类型的注解,如果没有则使用其实现接口的注解 for
(Class<?> clazz : target.getInterfaces()) { resolveDataSource(clazz,
signature.getMethod()); } resolveDataSource(target, signature.getMethod()); }
/** * 提取目标对象方法注解和类型注解中的数据源标识 * * @param clazz * @param method */ private void
resolveDataSource(Class<?> clazz, Method method) { try { Class<?>[] types =
method.getParameterTypes();// 默认使用类型注解 if
(clazz.isAnnotationPresent(DataSource.class)) { DataSource source =
clazz.getAnnotation(DataSource.class);
DynamicDataSourceHolder.setDataSource(source.value()); }// 方法注解可以覆盖类型注解 Method
m = clazz.getMethod(method.getName(), types);if (m != null &&
m.isAnnotationPresent(DataSource.class)) { DataSource source =
m.getAnnotation(DataSource.class);
DynamicDataSourceHolder.setDataSource(source.value()); } }catch (Exception e) {
System.out.println(clazz +":" + e.getMessage()); } } }
DynamicDataSourceHolder 类文件
public class DynamicDataSourceHolder { /** * 注意:数据源标识保存在线程变量中,避免多线程操作数据源时互相干扰
*/ private static final ThreadLocal<String> THREAD_DATA_SOURCE = new
ThreadLocal<String>();public static String getDataSource() { return
THREAD_DATA_SOURCE.get(); }public static void setDataSource(String dataSource)
{ THREAD_DATA_SOURCE.set(dataSource); }public static void clearDataSource() {
THREAD_DATA_SOURCE.remove(); } }
MultipleDataSource 类文件
注意此文件是要给spring-mybatis.xml文件调用所需要的
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
/** * 多数据源使用 * @author:lujingyu * @data:2018年9月15日下午2:33:40 */ public class
MultipleDataSource extends AbstractRoutingDataSource { @Override protected
ObjectdetermineCurrentLookupKey() { // 从自定义的位置获取数据源标识 return
DynamicDataSourceHolder.getDataSource(); } }
jdbc.properties 配置文件
文件说明:主要看两个数据源的配置
应该都很简单,通用配置根据自己的需要去使用,也可以都拿过来使用,但是如果你要修改,那么spring-mybatis.xml配置的时候就要以此修改
#mysql数据源 使用该数据库查询时候 请在ServiceImpl类中增加注解:@DataSource("dataSource") jdbc
.driverClassName=com.mysql.jdbc.Driver jdbc.url=jdbc\:mysql\://192.168.0.167\:
3306/online_db jdbc.username=root jdbc.password=123456 #sqlserver数据源 使用该数据库查询时候
请在ServiceImpl类中增加注解:@DataSource("sqlServerDataSource") jdbc.sqlserver.driver=net
.sourceforge.jtds.jdbc.Driver jdbc.sqlserver.url=jdbc:jtds:sqlserver://192.168.0
.117:1433/test_db jdbc.sqlserver.username=lujingyu jdbc.sqlserver.password=
123456 #通用配置 jdbc.initialSize=3 jdbc.minIdle=2 jdbc.maxActive=60 jdbc.maxWait=
60000 jdbc.timeBetweenEvictionRunsMillis=60000 jdbc.minEvictableIdleTimeMillis=
30000 jdbc.validationQuery=SELECT 'x' jdbc.testWhileIdle=true jdbc.testOnBorrow
=false jdbc.testOnReturn=false jdbc.poolPreparedStatements=true jdbc
.maxPoolPreparedStatementPerConnectionSize=20 jdbc.removeAbandoned=true jdbc
.removeAbandonedTimeout=120 jdbc.logAbandoned=false jdbc.filters=stat
spring-mybatis.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:aop=
"http://www.springframework.org/schema/aop" xmlns:tx=
"http://www.springframework.org/schema/tx" xmlns:context=
"http://www.springframework.org/schema/context" xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee-4.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.0.xsd"> <!-- 自动扫描(自动注入) -->
<context:component-scan base-package=
"com.newcsp.*.service;com.newcsp.*.*.service" /> <!-- 定时任务 --> <!--
<context:component-scan base-package="com.newcsp.common.timer"/> --> <bean id=
"log-filter" class="com.alibaba.druid.filter.logging.Log4jFilter"> <property
name="resultSetLogEnabled" value="true" /> </bean> <!--
重要!!!配置数据源mysql的下面的property 根据你jdbc.properties文件去配 --> <bean name="dataSource"
class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method
="close"> <property name="driverClassName" value="${jdbc.driverClassName}" /> <
property name="url" value="${jdbc.url}" /> <property name="username" value=
"${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> <
property name="initialSize" value="${jdbc.initialSize}" /> <property name=
"minIdle" value="${jdbc.minIdle}" /> <property name="maxActive" value=
"${jdbc.maxActive}" /> <property name="maxWait" value="${jdbc.maxWait}" /> <
property name="timeBetweenEvictionRunsMillis" value=
"${jdbc.timeBetweenEvictionRunsMillis}" /> <property name=
"minEvictableIdleTimeMillis" value="${jdbc.minEvictableIdleTimeMillis}" /> <
property name="validationQuery" value="${jdbc.validationQuery}" /> <property
name="testWhileIdle" value="${jdbc.testWhileIdle}" /> <property name=
"testOnBorrow" value="${jdbc.testOnBorrow}" /> <property name="testOnReturn"
value="${jdbc.testOnReturn}" /> <property name="removeAbandoned" value=
"${jdbc.removeAbandoned}" /> <property name="removeAbandonedTimeout" value=
"${jdbc.removeAbandonedTimeout}" /> <!-- <property name="logAbandoned"
value="${jdbc.logAbandoned}" /> --> <property name="filters" value=
"${jdbc.filters}" /> <!-- 关闭abanded连接时输出错误日志 --> <property name="logAbandoned"
value="true" /> <property name="proxyFilters"> <list> <ref bean="log-filter" />
</list> </property> <!-- 监控数据库 --> <!-- <property name="filters" value="stat"
/> --> <!-- <property name="filters" value="mergeStat" /> --> </bean>
<!--重要!!!! sqlserver数据源 可以用这个配置做参考 mysql的加了一些功能配置 --> <bean id=
"sqlServerDataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close"> <property name="driverClassName" value=
"${jdbc.sqlserver.driver}"/> <property name="url" value="${jdbc.sqlserver.url}"
/> <property name="username" value="${jdbc.sqlserver.username}"/> <property name
="password" value="${jdbc.sqlserver.password}"/> <property name="initialSize"
value="${jdbc.initialSize}"/> <property name="minIdle" value="${jdbc.minIdle}"/>
<property name="maxActive" value="${jdbc.maxActive}"/> <property name="maxWait"
value="${jdbc.maxWait}"/> <property name="validationQuery" value=
"${jdbc.validationQuery}" /> <property name="testWhileIdle" value=
"${jdbc.testWhileIdle}"/> <property name="testOnBorrow" value=
"${jdbc.testOnBorrow}" /> <property name="testOnReturn" value=
"${jdbc.testOnReturn}" /> <property name="removeAbandoned" value=
"${jdbc.removeAbandoned}"/> <property name="removeAbandonedTimeout" value=
"${jdbc.removeAbandonedTimeout}"/> <property name=
"timeBetweenEvictionRunsMillis" value="${jdbc.timeBetweenEvictionRunsMillis}"/>
<property name="minEvictableIdleTimeMillis" value=
"${jdbc.minEvictableIdleTimeMillis}"/> </bean> <!-- 重要!!! 此处的class调用的就是上面的一个类文件
--> <bean id="multipleDataSource" class=
"com.newcsp.core.mybatis.MultipleDataSource"> <!-- 指定默认的数据源 --> <property name=
"defaultTargetDataSource" ref="dataSource"/> <property name="targetDataSources">
<map> <!-- 两个数据源的名称 --> <entry key="dataSource" value-ref="dataSource"/> <entry
key="sqlServerDataSource" value-ref="sqlServerDataSource"/> </map> </property>
</bean> <bean id="sqlSessionFactory" class=
"org.mybatis.spring.SqlSessionFactoryBean"> <!--单数据源使用 课忽略 --> <!-- <property
name="dataSource" ref="dataSource" /> --> <!--重要!!!!多数据源使用 --> <property name=
"dataSource" ref="multipleDataSource"/> <property name="configLocation" value=
"classpath:mybatis-config.xml" /> <property name="mapperLocations"> <list> <
value>classpath:com/newcsp/oracle/mapper/*.xml</value> </list> </property> </
bean> <bean id="sqlSessionTemplate" class=
"org.mybatis.spring.SqlSessionTemplate"> <constructor-arg index="0" ref=
"sqlSessionFactory" /> </bean> <bean id="baseMybatisDao" class=
"com.newcsp.core.mybatis.BaseMybatisDao"> <property name="sqlSessionFactory" ref
="sqlSessionFactory" /> </bean> <bean class=
"org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name=
"basePackage" value="com.newcsp.oracle.dao" /> <property name=
"sqlSessionFactoryBeanName" value="sqlSessionFactory" /> </bean> <bean id=
"transactionManager" class=
"org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property
name="dataSource" ref="dataSource" /> </bean> <tx:advice id="txAdvice"
transaction-manager="transactionManager"> <tx:attributes> <tx:method name=
"publish*" /> <tx:method name="save*" /> <tx:method name="add*" /> <tx:method
name="update*" /> <tx:method name="insert*" /> <tx:method name="create*" /> <
tx:method name="del*" /> <tx:method name="load*" /> <tx:method name="init*" /> <
tx:method name="*" read-only="true" /> </tx:attributes> </tx:advice> <!-- AOP配置
--> <aop:config> <aop:pointcut id="myPointcut" expression="execution(public *
com.newcsp.*.service.impl.*.*(..))" /> <aop:advisor advice-ref="txAdvice"
pointcut-ref="myPointcut" /> </aop:config>
<!--重要!!!!!此处用于拦截serverimpl层dataSource注解 用于多数据源使用 --> <bean id=
"dataSourceAspect" class="com.newcsp.core.mybatis.DataSourceAspect" /> <
aop:config> <aop:aspect ref="dataSourceAspect"> <!-- 拦截所有service方法 --> <
aop:pointcut id="dataSourcePointcut" expression="execution(*
com.newcsp.*.service.*.*(..))" /> <aop:before pointcut-ref="dataSourcePointcut"
method="intercept" /> </aop:aspect> </aop:config> </beans>
使用方法介绍:
在spring-mybatis.xml 中配置了拦截注解@DataSource的方法
在写代码的使用不论怎么写都是要经过serviceImpl实现层的 ,在实现层中加注解
例如:@DataSource(“dataSource”)
因为在配置spring-mybatis.xml 的时候 我的mysql配置name叫:dataSource
我的sqlserver配置name叫sqlServerDataSource,需要使用哪个数据库就加这个数据库的注解名就可以了!
例如:
@Service @DataSource("dataSource") public class UserServiceImpl implements
UserService { }
到此结束,不懂可以交流。欢迎关注!
如果我成功的帮助到您~~您随便施舍一下都可以~