项目中遇到需要切换数据源的问题,网上找了些资料整理如下
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>