注解优雅解决Springboot+mybatis多数据配置问题

最近在开发项目中(ORM层用的是mybatis),需要连接多个数据库,这时候就涉及到多数据源使用了。为了优雅的解决此问题,我们可以使用装饰者模式来优雅的解决此问题 代码https://github.com/skybluehhx/mulitDataSource.git(现已更新支持注解的方式)。

 首先回顾下数据也就是DataSource这个接口的作用

public interface DataSource  extends CommonDataSource, Wrapper {

  /**
   * 尝试使用该数据源去获取连接
   */
  Connection getConnection() throws SQLException;

  /**
   * 
   */
  Connection getConnection(String username, String password)
    throws SQLException;
}

  假设现在我们有两个数据源A和B,我们可以使用自写一个数据源实现C,根据我们的需求从A或B中去获取具体实现,伪代码如下

 

/**
 * @author jianglinzou
 * @date 2019/7/4 下午7:52
 */
public class C implements DataSource {

    private DataSource A;

    private DataSource B;

    @Override
    public Connection getConnection() throws SQLException {
        return null;
    }

    @Override
    public Connection getConnection(String username, String password) throws SQLException {
        if (需要获取A数据源的连接) {
            return A.getConnection(username, password);
        } else if (需要获取B数据源的连接) {
            return B.getConnection(username, password);
        }

        return null;
    }
    //其他方法略
}

首先,根据我们的请求依据什么去获取具体的数据源连接,这个可以在request中确定,当发起请求时,我们需要自己去设置请求的数据源,

第二,由于request位于controller层,如何无缝的从request中获取需要请求的数据源名称呢,答案是通过threadlocal类,当请求来临时,我们从request中获取需要的数据名称,并放入threadlocal中,由于执行该方法与放入threadlocal的线程为同一线程,获取时我们直接从threadlocal中获取中即可。核心代码如下

 

//拦截器,从request中获取需要的数据源名称
   @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception {
        String dataSource = request.getParameter(DATA_SOURCE_PARAM_NAME);
        if (Strings.isBlank(dataSource)) {
            dataSource = request.getHeader(DATA_SOURCE_PARAM_NAME);
        }
      //该方法将需要的dataSource放入threadlocal中国
        MulitDataSourceSupport.putDataSourceName(request, dataSource);
        return true;
    }

  获取连接
 public Connection getConnection(String username, String password) throws 
 SQLException {
        DataSource dataSource = getDataSource();
        return dataSource.getConnection(username, password);

    }


 protected DataSource getDataSource() {
         String dataSourceName = MulitDataSourceSupport.getDataSourceName();
        logger.info("will to get dataSourceName:{}", dataSourceName);
        DataSource dataSource = getDataSourceFromApplication(dataSourceName);
        return dataSource;

    }

另一种方式是依托于注解,这里就不演示了,大家可以https://github.com/skybluehhx/mulitDataSource.git上获取完整代码

上述就是多数据源配置的核心代码,巧妙的运用了装饰者模式来解决实际问题,上述只是简单的讲解,大家获取完整的代码。根据readme提示运行实例即可。

 

 

你可能感兴趣的:(java)