项目中遇到需要切换数据源的问题,网上找了些资料整理如下
import java.util.HashMap;
import java.util.Map;
/**
*这个类主要切换当前线程的数据源
*/
public class DataSourceContextHolder {
// 线程本地环境,保存当前线程所持有的数据源key
private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();
// 设置数据源类型
public static void setDbType(String dbType) {
contextHolder.set(dbType);
}
// 获取数据源类型
public static String getDbType() {
return (contextHolder.get());
}
// 清除数据源类型
public static void clearDbType() {
contextHolder.remove();
}
}
import org.apache.commons.dbcp.BasicDataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
import java.util.HashMap;
import java.util.Map;
/**
*继承数据库路由类AbstractRoutingDataSource
*/
public class DynamicDataSource extends AbstractRoutingDataSource {
private static final Logger log = LoggerFactory.getLogger(DynamicDataSource.class);
@Override
protected Object determineCurrentLookupKey() {
return DataSourceContextHolder.getDbType();
}
/**
* 初始化多数据源
*
* @throws Exception
*/
private void initailizeMutiDataSource() throws Exception {
//保存数据源
Map<Object, Object> dataSourceMap = new HashMap<>();
PropertiesLoader propertiesLoader = new PropertiesLoader("jdbc.properties");
// 构造数据库连接
BasicDataSource basicDataSource = new BasicDataSource();
//驱动程序
basicDataSource.setDriverClassName(propertiesLoader.getProperty("driver"));
//url
basicDataSource.setUrl(propertiesLoader.getProperty("url"));
//用户名
basicDataSource.setUsername(propertiesLoader.getProperty("username"));
//密码
basicDataSource.setPassword(propertiesLoader.getProperty("password"));
//定义初始连接数
basicDataSource.setInitialSize(0);
//定义最大连接数
basicDataSource.setMaxActive(20);
//定义最大空闲
basicDataSource.setMaxIdle(20);
//定义最小空闲
basicDataSource.setMinIdle(1);
//定义最长等待时间
basicDataSource.setMaxWait(60000);
dataSourceMap.put("datasourceA", basicDataSource);
dataSourceMap.put("datasourceB", basicDataSource);
//这里可以构建存储多个数据源,本人嫌麻烦,只写了一个
setTargetDataSources(dataSourceMap);
setDefaultTargetDataSource(dataSourceMap.values().iterator().next());
//切换数据源的时候调用DataSourceContextHolder.setDbType("datasourceA"),若不调用则会使用默认的数据源DefaultTargetDataSource
//将保存的key值传入即可
//连接库之前会调用determineCurrentLookupKey()方法获取,根据key值到TargetDataSources找到对应的数据库连接
}
@Override
public void afterPropertiesSet() {
try {
initailizeMutiDataSource();
} catch (Exception e) {
log.error(e.getMessage());
}
super.afterPropertiesSet();
}
}
之后在配置文件中配置数据源即可,关键代码
<!-- 多数据源配置 -->
<bean id="dataSource" class="com.test.DynamicDataSource">
</bean>
<!-- spring和MyBatis整合 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="configLocation" value="classpath:mybatis-config.xml"></property>
<!-- 自动扫描xxxmapper.xml文件 -->
<property name="mapperLocations" value="classpath:mapper/*.xml"/>
</bean>