基本架構
SpringBoot+MybatisPlus實現多數據源,借助Spring-AOP實現數據源的動態切換.
整體流程
-
定義注解,使用該注解配置具體方法使用的數據源,用於指明方法使用的數據源github
-
定義通知advice:實現接口MethodBeforeAdvice, AfterReturningAdvice,用於在方法的執行前后切換數據源
-
定義切面:這里通過實現接口PointcutAdvisor定義切面,其中定義切點覆蓋所有需要攔截的方法(需要操作數據庫的方法),引入具體的通知,即上一步定義的advice,並通過注解@Component將其注入到spring容器中
-
定義封裝數據源的工具類,使用ThreadLocal存儲,通過字符串區分所使用的數據源
public class DataSourceHolder { private static final ThreadLocal<String> DATA_SOURCES = new ThreadLocal<>(); public static void setDataSources(String customerType) { DATA_SOURCES.set(customerType); } public static String getDataSource() { return DATA_SOURCES.get(); } public static void clearDataSource() { DATA_SOURCES.remove(); } } -
配置數據源的bean,並自定義動態數據源類實現接口AbstractRoutingDataSource,重寫determineCurrentLookupKey方法返回多數據源具體的key
public class DynamicDataSource extends AbstractRoutingDataSource { @Override protected Object determineCurrentLookupKey() { return DataSourceHolder.getDataSource(); } } -
配置SqlSessionFactory的bean,設置其數據源為自定義的動態數據源(設置默認數據源以及多數據源Map)
@Bean public SqlSessionFactory sqlSessionFactoryBean() throws Exception { MybatisSqlSessionFactoryBean sqlSessionFactory = new MybatisSqlSessionFactoryBean(); // 配置數據源,此處配置為關鍵配置,如果沒有將 dynamicDataSource作為數據源則不能實現切換 sqlSessionFactory.setDataSource(dynamicDataSource()); // 掃描Model sqlSessionFactory.setTypeAliasesPackage("com.zdk.**.entity"); return sqlSessionFactory.getObject(); } @Bean public DynamicDataSource dynamicDataSource() { DynamicDataSource dataSource = new DynamicDataSource(); Map<Object, Object> targetDataSource = new HashMap<>(16); targetDataSource.put("hello-world", helloWorldDataSource()); targetDataSource.put("zdk-data", zdkDataDataSource()); dataSource.setTargetDataSources(targetDataSource); dataSource.setDefaultTargetDataSource(helloWorldDataSource()); return dataSource; }
注意
- 切點的定義問題,注意切點的正則表達式能否覆蓋到所有涉及到數據庫操作的方法
- 在MybatisPlus中使用MybatisSqlSessionFactoryBean作為SqlSessionFactory而非SqlSessionFactoryBean
