最近在开发一个项目,需要访问另一个项目的数据,由于两个数据库是部署在同一个服务器上,且本项目只是对另一数据读取,因此决定在项目中使用双数据源配置进行访问。
系统都是基于Sprin个MVC+Mybatis的架构,配置双数据源主要包括以下几个步骤:
1.修改配置文件(数据源配置文件,数据库连接属性文件)
2.添加数据库处理类源码
3.代码中动态调用数据库
具体实现(黑色加粗部分是关键代码):
1.修改配置文件(数据源配置文件,数据库连接属性文件)
数据库连接属性文件
#数据库1
jdbc.type=mysql
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/db1?useUnicode=true&characterEncoding=utf-8
jdbc.username=root
jdbc.password=111111
#数据库2
jdbc.db2_url=jdbc:mysql://localhost:3306/db2?useUnicode=true&characterEncoding=utf-8
jdbc.db2_username=root
jdbc.db2_password=111111
数据源属性配置文件
2.添加数据库处理类源码
添加数据库切换类
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
/**
* 数据源切换
* 通过继承AbstractRoutingDataSource类来实现数据源切换
*/
public class DynamicDataSource extends AbstractRoutingDataSource {
private static final ThreadLocal
public static String getCurrentLookupKey() {
return (String) contextHolder.get();
}
public static void setCurrentLookupKey(String currentLookupKey) {
contextHolder.set(currentLookupKey);
}
@Override
protected Object determineCurrentLookupKey() {
return getCurrentLookupKey();
}
}
3.代码中动态调用数据库
调用数据库2
DynamicDataSource.setCurrentLookupKey("dataSource2");
切换回数据库1
DynamicDataSource.setCurrentLookupKey("dataSource");
ok,到这我们就已经可以实现了业务代码中切换数据源获取数据了。
但是以上方法有一个问题,如果我的业务很多,那我就需要经常在代码中去频繁的调用切换数据源的代码进行数据库切换,那样可能会引发几个问题:
1.业务代码执行完,数据源忘记切换回默认数据源,导致下一次业务执行时,数据连接还保留在数据源2,那样系统去取数据时,就会报错。
2.复杂的业务代码执行过程中可能需要来回切换数据源获取数据,一不小心可能就会因为忘记调用切换代码引发异常。
在这提供两个解决思路(不提供源代码,只希望你能自己动动手去实现):
1.对业务进行归类,对于只需要切换一次数据源就可以完成的,进行归类,然后用拦截器进行统一处理,进入业务之前先做数据源切换,等业务执行完后退出的时候,再将数据源切换回默认的数据源。缺点是这个仅仅只针对业务简单的方法调用,一个方法里要来回调用好几次数据切换的话,那这个方法没办法实现。
2.可以通过注解的方式来实现,不过个人觉得注解的方式会比较麻烦,毕竟要在每个方法上面添加注解。缺点跟思路1一样,毕竟复杂的业务还是要做一下分解,一个方法几百行的代码,看起来也是很头疼把。
如果想使用mysql基于federated存储引擎来实现,可以参见我另一篇文章:mysql基于federated存储引擎访问远程数据库表
也许你有更好的方法,也许你觉得我文章中的某些地方写的不对或者不够完善,欢迎给我留言。