您好,登錄后才能下訂單哦!
這期內容當中小編將會給大家帶來有關在Mybatis plus中如何實現配置多數據源,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。
一. mybatis plus
因為我們項目是springboot+mybatis plus,有些人一看,mybatis還知道對吧,mybatis plus是什么鬼,其實字面意思可以理解,就是對mybatis進行一些功能改造,一些封裝升級,然后用起來特別方便。
核心功能的升級主要是以下三點:
支持通用的 CRUD、代碼生成器與條件構造器。
通用 CRUD:定義好 Mapper 接口后,只需要繼承 BaseMapper<T> 接口即可獲得通用的增刪改查功能,無需編寫任何接口方法與配置文件
條件構造器:通過 EntityWrapper<T> (實體包裝類),可以用于拼接 SQL 語句,并且支持排序、分組查詢等復雜的 SQL
代碼生成器:支持一系列的策略配置與全局配置,比 MyBatis 的代碼生成更好用
二.多數據源配置開始
思路:
1、yml中配置多個數據源信息
2、通過AOP切換不同數據源
3、配合mybatis plus使用
1、yml配置
spring: aop: proxy-target-class: true auto: true datasource: druid: db1: url: jdbc:mysql://localhost:3306/eboot username: root password: root driver-class-name: com.mysql.jdbc.Driver initialSize: 5 minIdle: 5 maxActive: 20 db2: url: jdbc:oracle:thin:@192.168.136.222:ORCL username: sa password: sa123456 driver-class-name: oracle.jdbc.OracleDriver initialSize: 5 minIdle: 5 maxActive: 20
2、啟動多個數據源
@EnableTransactionManagement //開啟事務 @Configuration //spring中常用到注解,與xml配置相對立。是兩種加載bean方式 @MapperScan("com.df.openapi.**.mapper.db*") // 掃描mapperdao的地址 public class MybatisPlusConfig { @Bean public PaginationInterceptor paginationInterceptor() { PaginationInterceptor paginationInterceptor = new PaginationInterceptor(); // paginationInterceptor.setLocalPage(true); // 由于版本問題,有些類可能招不到這個方法,需要升級jar包 return paginationInterceptor; } @Bean(name = "db1") @ConfigurationProperties(prefix = "spring.datasource.druid.db1") public DataSource db1() { return DruidDataSourceBuilder.create().build(); } @Bean(name = "db2") @ConfigurationProperties(prefix = "spring.datasource.druid.db2") public DataSource db2() { return DruidDataSourceBuilder.create().build(); } /** * 動態數據源配置 * * @return */ @Bean @Primary public DataSource multipleDataSource(@Qualifier("db1") DataSource db1, @Qualifier("db2") DataSource db2) { DynamicDataSource dynamicDataSource = new DynamicDataSource(); Map<Object, Object> targetDataSources = new HashMap<>(); targetDataSources.put(DBTypeEnum.db1.getValue(), db1); targetDataSources.put(DBTypeEnum.db2.getValue(), db2); dynamicDataSource.setTargetDataSources(targetDataSources); dynamicDataSource.setDefaultTargetDataSource(db2); // 程序默認數據源,這個要根據程序調用數據源頻次,經常把常調用的數據源作為默認 return dynamicDataSource; } @Bean("sqlSessionFactory") public SqlSessionFactory sqlSessionFactory() throws Exception { MybatisSqlSessionFactoryBean sqlSessionFactory = new MybatisSqlSessionFactoryBean(); sqlSessionFactory.setDataSource(multipleDataSource(db1(), db2())); MybatisConfiguration configuration = new MybatisConfiguration(); configuration.setJdbcTypeForNull(JdbcType.NULL); configuration.setMapUnderscoreToCamelCase(true); configuration.setCacheEnabled(false); sqlSessionFactory.setConfiguration(configuration); //PerformanceInterceptor(),OptimisticLockerInterceptor() //添加分頁功能 sqlSessionFactory.setPlugins(new Interceptor[]{ paginationInterceptor() }); // sqlSessionFactory.setGlobalConfig(globalConfiguration()); //注釋掉全局配置,因為在xml中讀取就是全局配置 return sqlSessionFactory.getObject(); } /* @Bean public GlobalConfiguration globalConfiguration() { GlobalConfiguration conf = new GlobalConfiguration(new LogicSqlInjector()); conf.setLogicDeleteValue("-1"); conf.setLogicNotDeleteValue("1"); conf.setIdType(0); conf.setMetaObjectHandler(new MyMetaObjectHandler()); conf.setDbColumnUnderline(true); conf.setRefresh(true); return conf; }*/ }
3、DBType枚舉類
package com.df.openapi.config.db; public enum DBTypeEnum { db1("db1"), db2("db2"); private String value; DBTypeEnum(String value) { this.value = value; } public String getValue() { return value; } }
4、動態數據源決策
package com.df.openapi.config.db; import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; public class DynamicDataSource extends AbstractRoutingDataSource { private static final Logger LOGGER = LoggerFactory.getLogger(DynamicDataSource.class); @Override protected Object determineCurrentLookupKey() { String datasource = DataSourceContextHolder.getDbType(); LOGGER.debug("使用數據源 {}", datasource); return datasource; } }
5、設置、獲取數據源
public class DataSourceContextHolder { private static final Logger LOGGER = LoggerFactory.getLogger(DataSourceContextHolder.class); private static final ThreadLocal contextHolder = new ThreadLocal<>(); //實際上就是開啟多個線程,每個線程進行初始化一個數據源 /** * 設置數據源 * @param dbTypeEnum */ public static void setDbType(DBTypeEnum dbTypeEnum) { contextHolder.set(dbTypeEnum.getValue()); } /** * 取得當前數據源 * @return */ public static String getDbType() { return (String) contextHolder.get(); } /** * 清除上下文數據 */ public static void clearDbType() { contextHolder.remove(); } }
6、AOP實現的數據源切換
@Order設置的足夠小是為了讓他先執行
/** * aop的實現的數據源切換<br> * aop切點,實現mapper類找尋,找到所屬大本營以后,如db1Aspect(),則會調用<br> * db1()前面之前的操作,進行數據源的切換。 */ @Component @Order(value = -100) @Slf4j @Aspect public class DataSourceAspect { @Pointcut("execution(* com.zwyl.bazhong.dao.mapper.db1..*.*(..))") private void db1Aspect() { } @Pointcut("execution(* com.zwyl.bazhong.dao.mapper.db2..*.*(..))") private void db2Aspect() { } @Before("db1Aspect()") public void db1() { log.info("切換到db1 數據源..."); DataSourceContextHolder.setDbType(DBTypeEnum.db1); } @Before("db2Aspect()") public void db2() { log.info("切換到db2 數據源..."); DataSourceContextHolder.setDbType(DBTypeEnum.db2); } }
7、mapper層結構
8、寫一個service測試一下
@Service public class DictServiceImpl implements IDictService { @Resource private PtDictMapper ptDictMapper; //來自db1 @Resource private SysDictMapper sysDictMapper; // 來自db2 @Override public void getById(String id) { PtDict dict = ptDictMapper.selectById("2bf6257fc8fe483c84c1ad7e89d632f6"); SysDict sysDict = sysDictMapper.getById("49"); System.out.println("123"); } }
9、測試結果
總結: 其實整個過程可以理解成,配置多數據源 xml中 -------> 然后通過加載多數源到spring工廠中-------->然后創建多線程,每個數據源對應一個數據源--------->然后實際調用時候,會先通過aop匹配到某一具體數據源------------->然后實例化當前數據源
上述就是小編為大家分享的在Mybatis plus中如何實現配置多數據源了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。