1. 继承AbstractRoutingDataSource

1.1. 设置数据源列表

1
private Map<Object, Object> targetDataSources;

targetDataSources的key类型必须是后续 determineCurrentLookupKey() 方法的返回值类型

1.2. 设置默认数据源数据源列表

1
private Object defaultTargetDataSource;

默认数据源,可以将读数据源引用过来。

1.3. 实现父类虚方法

1
2
3
4
5
6
7
8
/**
* Determine the current lookup key. This will typically be
* implemented to check a thread-bound transaction context.
* <p>Allows for arbitrary keys. The returned key needs
* to match the stored lookup key type, as resolved by the
* {@link #resolveSpecifiedLookupKey} method.
*/
protected abstract Object determineCurrentLookupKey();
1
2
3
4
5
6
public class DynamicDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return DataSourceContextHolder.getType();
}
}

2. 多数据源(读写分离)自动切换

使用AOP技术,拦截需要进行数据源(读写)分离的sql操作,执行操作:

1
2
DataSourceContextHolder.setType(Operation.READ);
DataSourceContextHolder.setType(Operation.WRITE);

多线程并发情况下,为保证线程安全,每个线程都有自己的数据源切换,可使用 ThreadLocal 封装 DataSourceContextHolder.getType()