SpringMVC+Mybatis 如何配置多个数据源并切换?

  最近公司一个项目需要连接两个数据库(A和B)操作,有的模块查询A库,有的模块查询B库,因此需要改造下,项目后台用的是SpringMVC+Mybatis+MySQL架构,折腾了两天后终于搞定了,在这里记录过改造过程。

  使用场景

  多数据源的使用的场景一般有:

  主从数据库切换读写分离兼容旧库

  实现原理

  Spring2.x的版本中采用Proxy模式,就是在方案中实现一个虚拟的数据源,并且用它来封装数据源选择逻辑,这样就可以有效地将数据源选择逻辑从Client中分离出来。Client提供选择所需的上下文,由虚拟的DynamicDataSource根据Client提供的上下文来实现数据源的选择。

  具体的实现是虚拟的DynamicDataSource仅需继承AbstractRoutingDataSource实现determineCurrentLookupKey(),该方法返回需要使用的DataSource的key值,然后根据这个key从resolvedDataSources这个map里取出对应的DataSource,如果找不到则用默认的resolvedDefaultDataSource。

  详细实现过程

  修改spring的配置文件配置文件里需要配置多个数据源,改造后主要配置如下:

  destroy-method="close" scope="singleton">

  destroy-method="close" scope="singleton">

  class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

  classpath*:com/test/**/*Mapper.xml

  2.添加动态数据源管理类

  DynamicDataSource类继承AbstractRoutingDataSource,实现determineCurrentLookupKey()方法。

  package com.test.util;

  import com.test.util.CustomerContextHolder;

  import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

  /**

  * 动态数据源管理类

  *

  */

  public class DynamicDataSource extends AbstractRoutingDataSource {

  @Override

  protected Object determineCurrentLookupKey() {

  return CustomerContextHolder.getCustomerType();

  }

  }

  3. 数据源切换类

  CustomerContextHolder类可以实现数据源A和B的切换,数据源标识保存在线程变量中,避免多线程操作数据源时互相干扰。

  package com.test.util;

  /**

  * 数据源切换类

  *

  */

  public class CustomerContextHolder {

  public static final String DATA_SOURCE_DEFAULT="dataSourceTargetA";

  public static final String DATA_SOURCE_B="dataSourceTargetB";

  private static final ThreadLocal contextHolder=new ThreadLocal();

  public static void setCustomerType(String customerType) {

  contextHolder.set(customerType);

  }

  public static String getCustomerType() {

  return contextHolder.get();

  }

  public static void clearCustomerType() {

  contextHolder.remove();

  }

  }

  4. 使用多数据源代码

  下面是Controller层代码,需要查询B数据源,查询完成后切换为默认数据源A,具体代码如下:

  /**

  * 订单列表查询,查询B数据源

  *

  * @param request

  * @return

  */

  @RequestMapping(value="/list")

  public String list(HttpServletRequest request, Integer cId) {

  //设置数据源B

  CustomerContextHolder.setCustomerType(CustomerContextHolder.DATA_SOURCE_B);

  List orderList=orderService.getListByCid(cId);

  request.setAttribute("orderList", orderList);

  //切换回默认数据源A

  CustomerContextHolder.setCustomerType(CustomerContextHolder.DATA_SOURCE_DEFAULT);

  return "/jsp/order";

  }

  上述四步操作完成后即可实现SpringMVC+Mybatis配置多个数据源并切换,有问题欢迎留言沟通哦!

posted @ 2022-09-03 14:20  ebuybay  阅读(484)  评论(0编辑  收藏  举报