java 连接2个数据源_Spring 配置多个数据源 并实现动态切换

本文介绍了如何在Java应用中使用Spring配置连接并动态切换两个数据源。首先,展示了`jdbc.properties`中配置两个数据源的详情,然后在Spring配置文件中进行相应的配置。接着,自定义`SurveyRouterDataSource`类继承`AbstractRoutingDataSource`,通过`determineCurrentLookupKey`方法实现数据源的动态切换。此外,还使用了`RouterToken`类来管理数据源的切换。在应用二中,通过AOP切面`DataSourceAspect`根据Service方法名判断读写操作,并切换数据源。最后,定义了`DynamicDataSource`类及`DBContextHolder`工具类来辅助数据源切换。
摘要由CSDN通过智能技术生成

应用一

主数据源和应用数据源(代码中手动切换数据源)

1.jdbc.properties(连接两个库)jdbc.user=root jdbc.password=123456 jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/survey?rewriteBatchedStatements=true log.url=jdbc:mysql://localhost:3306/survey_log?rewriteBatchedStatements=true

2.Spring配置文件的配置

3.定义一个类继承AbstractRoutingDataSource实现determineCurrentLookupKey方法,该方法可以实现数据库的动态切换,如下(方法返回的数据源的key值 根据key值去配响应的数据源)public class SurveyRouterDataSource extends AbstractRoutingDataSource{ @Override protected Object determineCurrentLookupKey() { //尝试从当前线程获取令牌 String token = RouterToken.getToken(); //检测令牌是否等于日志数据源对应的键 if(RouterToken.DATASOURCE_LOG.equals(token)){ //当前线程上的令牌,在使用过后需要移除 //避免影响当前线程内其他的数据库操作 RouterToken.removeToken(); //如果是日志数据源对应的键,将日志数据源的键返回 return RouterToken.DATASOURCE_LOG; } //如果不是日志数据源对应的键则返回null采用默认的数据源(主数据源) return null; } }

4.将路由器数据源的key值绑定到本地线程中/** * 连接数据源的令牌,返回字符串,根据返回的字符串名称判定连接那个数据源 * @author dongdong */ public class RouterToken { // 声明一个本地线程 private static ThreadLocal local = new ThreadLocal(); // 将返回的字符串声明为静态全局final形式的 public static final String DATASOURCE_LOG = "DATASOURCE_LOG"; // 将字符串绑定到线程上 public static void bindToken(String token) { local.set(token); } // 获取当前线程的字符串 public static String getToken() { return local.get(); } //将当前线程的字符串移除 public static void removeToken(){ local.remove(); } }

5.代码中的使用//将路由器数据源的key绑定到当前线程,必须在Service方法前绑定,因为Service有事物,事物也要连接数据源 RouterToken.bindToken(RouterToken.DATASOURCE_LOG); Page page = logService.getPage(pageNoStr, Page.PAGE_SIZE_SMALL);

应用二

主数据源和从数据源(AOP实现自动数据源的切换)

1.jdbc.propertiesssjdbc.driver=com.mysql.jdbc.Driver #主数据库 jdbc.master.url=jdbc:mysql://192.168.0.68:3306/master_lxg jdbc.master.username=root jdbc.master.password=root #从数据库 jdbc.slaver.url=jdbc:mysql://192.168.0.12:3306/slave_lxg jdbc.slaver.username=root jdbc.slaver.password=root

2.Spring配置文件的配置

3.定义数据源的AOP切面,通过该Service的方法名判断是应该走读库还是写库,并且设置数据源public class DataSourceAspect { /** * 在进入Service方法之前执行 */ public void before(JoinPoint point) { // 获取到当前执行的方法名 String methodName = point.getSignature().getName(); if (isSlave(methodName)) { // 标记为从库 应当先clear一下 DBContextHolder.clearDBType (); DBContextHolder.setDBType(DBContextHolder.DATA_SOURCE_SLAVER); } else { // 标记为主库 应当先clear一下 DBContextHolder.clearDBType (); DBContextHolder.setDBType(DBContextHolder.DATA_SOURCE_MASTER); } } /** * 判断是否为读库 */ private Boolean isSlave(String methodName) { // 方法名以query、find、get开头的方法名走从库 return StringUtils.startsWithAny(methodName, "query", "find", "get"); } }4.定义一个类继承AbstractRoutingDataSource实现determineCurrentLookupKey方法,该方法可以实现数据库的动态切换,如下(方法返回的数据源的key值 根据key值去配响应的数据源)

public class DynamicDataSource extends AbstractRoutingDataSource{ @Override protected Object determineCurrentLookupKey() { return DBContextHolder.getDBType(); } }5.将路由器数据源的key值绑定到本地线程中

public class DBContextHolder{ public static final String DATA_SOURCE_MASTER = "Master"; public static final String DATA_SOURCE_SLAVER = "Slaver"; private static final ThreadLocal THREAD_LOCAL = new ThreadLocal(); public static void setDBType(String dbType) { THREAD_LOCAL.set(dbType); } public static String getDBType() { return THREAD_LOCAL.get(); } public static void clearDBType() { THREAD_LOCAL.remove(); } }

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值