spring boot + mybatis實(shí)現(xiàn)動(dòng)態(tài)切換數(shù)據(jù)源實(shí)例代碼
前言
前幾天有個(gè)需求,需要使用不同的數(shù)據(jù)源,例如某業(yè)務(wù)要用A數(shù)據(jù)源,另一個(gè)業(yè)務(wù)要用B數(shù)據(jù)源。我上網(wǎng)收集了一些資料整合了一下,雖然最后這個(gè)需求不了了之了,但是多數(shù)據(jù)源動(dòng)態(tài)切換還是蠻好用的,所以記錄一下,或許以后有用呢?或者自己感興趣又想玩呢!
下面話不多說了,隨著小編來一起看看詳細(xì)的介紹吧
方法如下:
1.加個(gè)依賴
<dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.3.1</version> </dependency>
2.application.properties配置文件
#主從數(shù)據(jù)庫 master.db.driverClassName=com.mysql.jdbc.Driver master.db.url=jdbc:mysql://localhost:3306/cbd?characterEncoding=UTF-8&useUnicode=true&useSSL=false master.db.username=root master.db.password=admin slave.db.driverClassName=com.mysql.jdbc.Driver slave.db.url=jdbc:mysql://localhost:3306/cbd_test?characterEncoding=UTF-8&useUnicode=true&useSSL=false slave.db.username=root slave.db.password=admin mybatis.config-location= classpath:config/mybatis-config.xml mybatis.mapper-locations=classpath:mapper/**/*.xml
3.禁用springboot默認(rèn)加載數(shù)據(jù)源配置
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class}) public class Application { public static void main(String[] args) throws Exception { SpringApplication.run(Application.class, args); } }
4.數(shù)據(jù)源配置類
/** * 主數(shù)據(jù)源 */ @Configuration @ConfigurationProperties(prefix = "master.db") public class MasterDataSourceConfig { private String url; private String username; private String password; private String driverClassName; }
/** * 從數(shù)據(jù)源配置 */ @Configuration @ConfigurationProperties(prefix = "slave.db") public class SlaveDataSourceConfig { private String url; private String username; private String password; private String driverClassName; }
/** * 數(shù)據(jù)源配置類 */ @Configuration public class DataSourceComponent { @Resource private MasterDataSourceConfig masterDataSourceConfig; @Resource private SlaveDataSourceConfig slaveDataSourceConfig; @Bean(name = "master") public DataSource masterDataSource() { DataSource dataSource = new DataSource(); dataSource.setUrl(masterDataSourceConfig.getUrl()); dataSource.setUsername(masterDataSourceConfig.getUsername()); dataSource.setPassword(masterDataSourceConfig.getPassword()); dataSource.setDriverClassName(masterDataSourceConfig.getDriverClassName()); return dataSource; } @Bean(name = "slave") public DataSource slaveDataSource() { DataSource dataSource = new DataSource(); dataSource.setUrl(slaveDataSourceConfig.getUrl()); dataSource.setUsername(slaveDataSourceConfig.getUsername()); dataSource.setPassword(slaveDataSourceConfig.getPassword()); dataSource.setDriverClassName(slaveDataSourceConfig.getDriverClassName()); return dataSource; } @Primary//不加這個(gè)會(huì)報(bào)錯(cuò)。 @Bean(name = "multiDataSource") public MultiRouteDataSource exampleRouteDataSource() { MultiRouteDataSource multiDataSource = new MultiRouteDataSource(); Map<Object, Object> targetDataSources = new HashMap<>(); targetDataSources.put("master", masterDataSource()); targetDataSources.put("slave", slaveDataSource()); multiDataSource.setTargetDataSources(targetDataSources); multiDataSource.setDefaultTargetDataSource(masterDataSource()); return multiDataSource; } }
5.數(shù)據(jù)源上下文
/** * 數(shù)據(jù)源上下文 */ public class DataSourceContext { private static final ThreadLocal<String> contextHolder = new ThreadLocal<>(); public static void setDataSource(String value) { contextHolder.set(value); } public static String getDataSource() { return contextHolder.get(); } public static void clearDataSource() { contextHolder.remove(); } }
6.DataSource路由類
/* * 重寫的函數(shù)決定了最后選擇的DataSource */ public class MultiRouteDataSource extends AbstractRoutingDataSource { @Override protected Object determineCurrentLookupKey() { //通過綁定線程的數(shù)據(jù)源上下文實(shí)現(xiàn)多數(shù)據(jù)源的動(dòng)態(tài)切換,有興趣的可以去查閱資料或源碼 return DataSourceContext.getDataSource(); } }
7.使用,修改上下文中的數(shù)據(jù)源就可以切換自己想要使用的數(shù)據(jù)源了。
public UserVO findUser(String username) { DataSourceContext.setDataSource("slave"); UserVO userVO = userMapper.findByVO(username); System.out.println(userVO.getName()+"====================="); return null; }
這種是在業(yè)務(wù)中使用代碼設(shè)置數(shù)據(jù)源的方式,也可以使用AOP+注解的方式實(shí)現(xiàn)控制,方法多多!
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問大家可以留言交流,謝謝大家對(duì)腳本之家的支持。
相關(guān)文章
JFinal實(shí)現(xiàn)偽靜態(tài)的方法
JFinal 是基于 Java 語言的極速 WEB + ORM 框架,其核心設(shè)計(jì)目標(biāo)是開發(fā)迅速、代碼量少、學(xué)習(xí)簡單、功能強(qiáng)大、輕量級(jí)、易擴(kuò)展、Restful。這篇文章主要介紹了JFinal實(shí)現(xiàn)偽靜態(tài),需要的朋友可以參考下2018-04-04Java實(shí)現(xiàn)的可選擇及拖拽圖片的面板功能【基于swing組件】
這篇文章主要介紹了Java實(shí)現(xiàn)的可選擇及拖拽圖片的面板功能,涉及java基于swing組件選擇與操作圖片元素的相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2018-01-01Java代碼實(shí)現(xiàn)循環(huán)隊(duì)列的示例代碼
隊(duì)列作為基礎(chǔ)的數(shù)據(jù)結(jié)構(gòu),是程序員的入門課。也是所有程序員必須掌握的一種數(shù)據(jù)結(jié)構(gòu),隊(duì)列在程序中廣泛應(yīng)用,因此我們應(yīng)該對(duì)隊(duì)列有深入的了解,接下來我們通過代碼來對(duì)隊(duì)列這種數(shù)據(jù)結(jié)構(gòu)進(jìn)行深度解析,感興趣的朋友一起看看吧2021-09-09為什么JDK8中HashMap依然會(huì)死循環(huán)
這篇文章主要介紹了為什么JDK8中HashMap依然會(huì)死循環(huán),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09Springboot-Starter造輪子之自動(dòng)鎖組件lock-starter實(shí)現(xiàn)
這篇文章主要為大家介紹了Springboot-Starter造輪子之自動(dòng)鎖組件lock-starter實(shí)現(xiàn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-05-05BeanUtils.copyProperties復(fù)制不生效的解決
這篇文章主要介紹了BeanUtils.copyProperties復(fù)制不生效的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-09-09Idea?中控制啟動(dòng)命令的詳細(xì)過程?區(qū)分環(huán)境案例詳解
這篇文章主要介紹了Idea?中控制啟動(dòng)命令的詳細(xì)過程?區(qū)分環(huán)境案例詳解,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-08-08