本篇博客将演示使用spring+mybatis实现多数据源的配置,实现原理采用aop切面。开始学习前可以先搭建好spring+mybatis的工程。
#============================================================================
# 数据源01
#============================================================================
jdbc.one.driver=oracle.jdbc.driver.OracleDriver
jdbc.one.url=jdbc:oracle:thin:@127.0.0.1:1521:w1
jdbc.one.username=system
jdbc.one.password=123456
#============================================================================
# 数据源02
#============================================================================
jdbc.two.driver=com.mysql.jdbc.Driver
jdbc.two.url=jdbc:mysql://127.0.0.1:3306/hy?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true
jdbc.two.username=root
jdbc.two.password=123456
#============================================================================
# 数据源03
#============================================================================
jdbc.three.driver=com.mysql.jdbc.Driver
jdbc.three.url=jdbc:mysql://127.0.0.1:3306/webcen?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true
jdbc.three.username=root
jdbc.three.password=123456
#============================================================================
# 通用配置
#============================================================================
jdbc.initialSize=5
jdbc.minIdle=5
jdbc.maxIdle=20
jdbc.maxActive=100
jdbc.maxWait=100000
jdbc.defaultAutoCommit=false
jdbc.removeAbandoned=true
jdbc.removeAbandonedTimeout=600
jdbc.testWhileIdle=true
jdbc.timeBetweenEvictionRunsMillis=60000
jdbc.numTestsPerEvictionRun=20
jdbc.minEvictableIdleTimeMillis=300000
以上配置就不多说了。数据源01使用的是oracle数据源,数据源02、数据源03使用的是mysql数据源
在代码块的注释中有详细描述配置
classpath:properties/*.properties
package com.me.service;
public interface Datasource01 {
}
package com.me.service;
public interface Datasource02 {
}
package com.me.service;
public interface Datasource03 {
}
有人会问,写着东西干啥?不着急,我们看看后面的就知道了 (〃'▽'〃)
/**
* 多数据源java实现
*/
public class MultipleDataSource extends AbstractRoutingDataSource {
private static final ThreadLocal dataSourceKey = new InheritableThreadLocal();
public static void setDataSourceKey(String dataSource) {
dataSourceKey.set(dataSource);
}
@Override
protected Object determineCurrentLookupKey() {
return dataSourceKey.get();
}
}
/**
* 数据库链接自动切换AOP处理
* Order优先级设置到最高,因为在所有service方法调用前都必须把数据源确定
* Order数值越小优先级越高
*/
@Component
@Aspect
@Order(1)
public class MultipleDataSourceAspectAdvice {
private static final Logger LOGGER = Logger.getLogger(MultipleDataSourceAspectAdvice.class);
public MultipleDataSourceAspectAdvice() {
LOGGER.info("MultipleDataSourceAspectAdvice 加载成功");
}
/**
* 定义切面
*/
@Pointcut("execution(* com.me.service.*..*(..))")
public void pointCut() {
} // dataSourceOneKey // dataSourceTwoKey // dataSourceThreeKey
@Around("pointCut()")
public Object doAround(ProceedingJoinPoint jp) throws Throwable {
if (jp.getTarget() instanceof Datasource01) {
System.out.println("使用了数据源01");
LOGGER.debug("使用数据库链接:dataSourceOneKey");
MultipleDataSource.setDataSourceKey("dataSourceOneKey");
} else if (jp.getTarget() instanceof Datasource03) {
LOGGER.debug("使用数据库链接:dataSourceTwoKey");
MultipleDataSource.setDataSourceKey("dataSourceTwoKey");
} else if (jp.getTarget() instanceof Datasource02) {
LOGGER.debug("使用数据库链接:dataSourceThreeKey");
MultipleDataSource.setDataSourceKey("dataSourceThreeKey");
} else { // 默认是dataSourceOneKey
System.out.println("默认");
LOGGER.debug("使用数据库链接:dataSourceOneKey");
MultipleDataSource.setDataSourceKey("dataSourceOneKey");
}
return jp.proceed();
}
}
我们可以发现,在这里我们使用切面的方式,在执行com.me.service下的所有方法前都确定了使用了哪个数据源。而具体使用哪个数据源的判断是根据我的类继承了哪个datasource接口。例如,我现在要在我新写的类中使用数据源01,那么我就要实现DataSource01接口。
@Service
@Transactional("transactionManager")
public class TestCURDImpl implements TestCURD,Datasource01 {
private static final Logger logger = Logger.getLogger(TestCURDImpl.class);
@Override
public String testRequest() {
return null;
}
}
大家可以在service包下创建一个类,按我上面写的方法测试执行以下。测试执行下
我们看日志,发现已经切换到了数据源01。我们是怎么实现切换的呢?注意我们之前编写的配置文件,里面有配置了数据源的管理类:
到这里,我们的多数据源已经完成,可以放心写代码了(~ ̄▽ ̄)~ ,注意不同的数据源实现不同的接口!
为了方便大家的理解,上面我把配置文件先写在了前面,会和总结的有所不同。 总结如下:我们首先在配置文件 db.properties 中配置了三个不同的数据源。之后写了三个不同数据源对应的接口 DataSource01,DataSource02,DataSource03。编写了一个多数据源的管理类 :MultipleDataSource,再使用切面MultipleDataSourceAspectAdvice 在执行具体方法前切换数据源。最后在配置文件applicationContext-dao.xml中编写具体配置。后期我会再出springBoot+mybatis的多数据源配置。
最后不要忘记让spring去初始化我们的applicationContext-dao.xml配置文件及扫描相对应的类。