配置数据源地址、账号、密码
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url1=jdbc:mysql://ip1:3306/easywork?useUnicode=true&characterEncoding=UTF-8&useSSL=false
jdbc.username1=xxx
jdbc.password1=xxx!
jdbc.url2=jdbc:mysql://ip2:3306/easywork?useUnicode=true&characterEncoding=UTF-8&useSSL=false
jdbc.username2=xxx
jdbc.password2=xxx
druid.pool.size.max=20
druid.pool.size.min=3
druid.pool.size.init=3
xml中配置数据源
数据源切换工具类
枚举类
public enum DataSourceEnum {
DS1("ds1"), DS2("ds2");
private String key;
DataSourceEnum(String key) { this.key = key; }
public String getKey() { return key; }
public void setKey(String key) { this.key = key; }
}
创建DynamicDataSourceHolder用于持有当前线程中使用的数据源标识
/**
* DynamicDataSourceHolder用于持有当前线程中使用的数据源标识
*/
public class DataSourceHolder {
private static final ThreadLocal dataSources = new ThreadLocal();
public static void setDataSources(String dataSource) {
dataSources.set(dataSource);
}
public static String getDataSources() {
return dataSources.get();
}
}
创建DynamicDataSource的类,继承AbstractRoutingDataSource并重写determineCurrentLookupKey方法
/**
* DynamicDataSource的类,继承AbstractRoutingDataSource并重写determineCurrentLookupKey方法
*/
public class DynamicDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return DataSourceHolder.getDataSources();
}
}
手动切换数据源
到这一步,已经可以试用各个数据源了,只需要在Service中查询前,调用一下即可
//teacherService
@Override
public TeacherVO getVOById(Integer id) {
DataSourceHolder.setDataSources(DataSourceEnum.DS2.getKey());
return teacherDao.getVOById(id);
}
//productService
@Override
public Product getPOById(Integer id) {
DataSourceHolder.setDataSources(DataSourceEnum.DS1.getKey());
return productDao.getPOById(id);
}
此时,两个方法分别从不同的数据源中查询数据
自动切换数据源
虽然可以手动切换数据源,但每个方法都切换太过麻烦,很容易忘记,所以可以利用AOP,进行自动切换数据源
创建切面类DataSourceExchange,切面的规则可以自定义,根据自己的项目做自己的规则,我这边是demo,所以product、teacher包分别用不同的数据源。
public class DataSourceExchange {
public void before(JoinPoint point) {
//获取目标对象的类类型
Class> aClass = point.getTarget().getClass();
String c = aClass.getName();
String[] ss = c.split("\\.");
//获取包名用于区分不同数据源
String packageName = ss[2];
if ("product".equals(packageName)) {
DataSourceHolder.setDataSources(DataSourceEnum.DS2.getKey());
System.out.println("数据源:"+DataSourceEnum.DS2.getKey());
} else {
DataSourceHolder.setDataSources(DataSourceEnum.DS1.getKey());
System.out.println("数据源:"+DataSourceEnum.DS1.getKey());
}
}
/**
* 执行后将数据源置为空
*/
public void after() {
DataSourceHolder.setDataSources(null);
}
}
配置切面
这样,在调用service方法时就会自动切换数据源了