目录
一、线程安全的数据源切换类(DataSourceSwitch.java)
在实际场景中,会遇到不同用户拥有不同的数据源,这些数据源信息配置在数据库表里面,需要我们根据用户切换成相应的数据源。在本文中,会介绍如何在SpringBoot + Mybatis中根据用户切换数据源的配置。
一、线程安全的数据源切换类(DataSourceSwitch.java)
将ThreadLocal封装成设置、保存、获取和清空当前线程所属用户的数据源的工具类,具体代码如下:
import javax.sql.DataSource;
/**
* 当前线程数据源工具类
*
* @author hrc
* @date 2019年1月29日
*/
public class DataSourceSwitch {
/**
* 保存数据源线程安全容器
*/
private static final ThreadLocal<DataSource> dataSourceThreadLocal = new ThreadLocal<DataSource>();
/**
* 设置数据源
* @param dataSource 数据源
*/
public static void setDataSource (DataSource dataSource) {
dataSourceThreadLocal.set(dataSource);
}
/**
* 获取数据源
* @return
*/
public static DataSource getDataSource(){
return (DataSource) dataSourceThreadLocal.get();
}
/**
* 清空数据源
*/
public static void clearDataSource(){
dataSourceThreadLocal.remove();
}
}
二、多数据源类(MultiDataSource.java)
多数据源类实现了DataSource接口,并且该类一个单例模式。在mybatis的sqlSessionFactory在创建一个sqlSession的时候会调用DataSource里的DataSource里的方法,并从中获取数据库连接。所以我们要实现多数据源,就只需要把多数据源的getDataSource()方法写成获取当前线程的数据源,并且把DataSource接口的方法改成getDataSource().xxx实现就行了。多数据源的具体实现代码如下:
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.logging.Logger;
import javax.sql.DataSource;
/**
* 多数据源类
*
* @author hrc
* @date 2019年1月29日
*/
public class MultiDataSource implements DataSource {
private static MultiDataSource multiDataSource = null;
private DataSource dataSource = null;
private MultiDataSource() {};
public static MultiDataSource getInstance() {
if(multiDataSource == null) {
synchronized (MultiDataSource.class) {
if (multiDataSource == null) {
multiDataSource = new MultiDataSource();
}
}
}
return multiDataSource;
}
public DataSource getDataSource() {
DataSource dataSource = DataSourceSwitch.getDataSource();
if (dataSource == null) {
dataSource = this.dataSource;
}
return dataSource;
}
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
@Override
public PrintWriter getLogWriter() throws SQLException {
return getDataSource().getLogWriter();
}
@Override
public void setLogWriter(PrintWriter out) throws SQLException {
getDataSource().setLogWriter(out);
}
@Override
public void setLoginTimeout(int seconds) throws SQLException {