spring boot多數(shù)據(jù)源動(dòng)態(tài)切換代碼實(shí)例
這篇文章主要介紹了spring boot多數(shù)據(jù)源動(dòng)態(tài)切換代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
當(dāng)項(xiàng)目中存在多數(shù)據(jù)源時(shí),就涉及到數(shù)據(jù)源的動(dòng)態(tài)切換,通過研究,特此記錄一下。
1、maven依賴
<!--數(shù)據(jù)庫連接-->
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>11.2.0.4</version>
<scope>runtime</scope>
</dependency>
<!--數(shù)據(jù)庫連接池->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!--aop->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
2、多數(shù)據(jù)源信息配置
#多數(shù)據(jù)源測(cè)試
spring:
datasource:
druid:
master:
driver-class-name: oracle.jdbc.driver.OracleDriver
username: test
password: test
url: jdbc:oracle:thin:@//ip1:1521/orcl
slave:
driver-class-name: oracle.jdbc.driver.OracleDriver
username: test
password: test
url: jdbc:oracle:thin:@//ip2:1521/orcl
3、數(shù)據(jù)源配置信息轉(zhuǎn)換成實(shí)體類
@ConfigurationProperties(prefix = "spring.datasource.druid")
@Data
@Component
public class DataSourceProperties {
private Map<String,String>master;
private Map<String,String>slave;
}
4、動(dòng)態(tài)數(shù)據(jù)源切換類
public class DynamicDataSource extends AbstractRoutingDataSource {
private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();
public DynamicDataSource(DataSource defaultTargetDataSource, Map<Object, Object> targetDataSources) {
super.setDefaultTargetDataSource(defaultTargetDataSource);
super.setTargetDataSources(targetDataSources);
super.afterPropertiesSet();
}
@Override
protected Object determineCurrentLookupKey() {
return getDataSource();
}
public static void setDataSource(String dataSource) {
contextHolder.set(dataSource);
}
public static String getDataSource() {
return contextHolder.get();
}
public static void clearDataSource() {
contextHolder.remove();
}
}
5、多數(shù)據(jù)源配置類
@Configuration
public class DynamicDataSourceConfig {
@Bean
public DataSource master(@Autowired DataSourceProperties dataSourceProperties){
DruidDataSource druidDataSource = new DruidDataSource();
Map<String, String> master = dataSourceProperties.getMaster();
druidDataSource.setUsername(master.get("username"));
druidDataSource.setPassword(master.get("password"));
druidDataSource.setUrl(master.get("url"));
//其他參數(shù)配置 省略
return druidDataSource;
}
@Bean
public DataSource slave(@Autowired DataSourceProperties dataSourceProperties){
DruidDataSource druidDataSource = new DruidDataSource();
Map<String, String> slave = dataSourceProperties.getSlave();
druidDataSource.setUsername(slave.get("username"));
druidDataSource.setPassword(slave.get("password"));
druidDataSource.setUrl(slave.get("url"));
//其他參數(shù)配置 省略
return druidDataSource;
}
@Bean
@Primary
public DynamicDataSource dataSource(DataSource master,DataSource slave){
Map<Object,Object>map = new HashMap<>(4);
map.put("master",master);
map.put("slave",slave);
return new DynamicDataSource(master,map);
}
}
6、自定義@DataSource注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface DataSource {
String name() default "master";
}
7、Aop切面類配置
@Component
@Aspect
public class DataSourceAspect {
@Pointcut("@annotation(com.zxgeo.sso.muiltDatasource.anons.DataSource)")
public void dataSourcePointCut(){}
@Around(value = "dataSourcePointCut()")
public Object around(ProceedingJoinPoint point) throws Throwable {
MethodSignature signature = (MethodSignature) point.getSignature();
Method method = signature.getMethod();
DataSource dataSource = method.getAnnotation(DataSource.class);
if(dataSource == null){
DynamicDataSource.setDataSource("master");
}else {
DynamicDataSource.setDataSource(dataSource.name());
}
try {
return point.proceed();
} finally {
DynamicDataSource.clearDataSource();
}
}
}
8、啟動(dòng)配置注解信息,重要(不然運(yùn)行會(huì)報(bào)錯(cuò))
@SpringBootApplication(exclude= {DataSourceAutoConfiguration.class})
9、測(cè)試
(1)、service層(此處沒有使用mybatis)
@Service
public class TestService {
@Autowired
private javax.sql.DataSource dataSource;
@DataSource
public Map<String,Object> getMasterDataSource() throws SQLException {
Connection connection = dataSource.getConnection();
Map<String,Object> map;
try (PreparedStatement preparedStatement
= connection.prepareStatement("SELECT * FROM AA WHERE A=10001")) {
ResultSet resultSet = preparedStatement.executeQuery();
map = new HashMap<>();
while (resultSet.next()){
map.put("A",resultSet.getString("A"));
map.put("B",resultSet.getString("B"));
map.put("C",resultSet.getString("C"));
}
}
return map;
}
@DataSource(name = "slave")
public Map<String,Object> getSlaveDataSource() throws SQLException {
Connection connection = dataSource.getConnection();
Map<String,Object> map;
try (PreparedStatement preparedStatement
= connection.prepareStatement("SELECT * FROM AA WHERE A=10002")) {
ResultSet resultSet = preparedStatement.executeQuery();
map = new HashMap<>();
while (resultSet.next()){
map.put("A",resultSet.getString("A"));
map.put("B",resultSet.getString("B"));
map.put("C",resultSet.getString("C"));
}
}
return map;
}
}
(2)、單元測(cè)試
@SpringBootTest
@RunWith(SpringRunner.class)
class SsoApplicationTests {
@Autowired
private TestService testService;
@Test
public void muliDatasorce() throws SQLException {
Map<String, Object> masterDataSourceUrl = testService.getMasterDataSource();
System.out.println(masterDataSourceUrl);
Map<String, Object> slaveDataSourceUrl = testService.getSlaveDataSource();
System.out.println(slaveDataSourceUrl);
}
}
(3)、結(jié)果:

以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Spring Cloud Zuul路由規(guī)則動(dòng)態(tài)更新解析
這篇文章主要介紹了Spring Cloud Zuul路由規(guī)則動(dòng)態(tài)更新解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-11-11
Java中兩個(gè)List之間的比較方法(差集、交集和并集)
在業(yè)務(wù)的開發(fā)過程中會(huì)經(jīng)常用到兩個(gè)List集合相互取值的情況,下面這篇文章主要給大家介紹了關(guān)于Java中兩個(gè)List之間的比較方法,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-06-06
java實(shí)現(xiàn)兩個(gè)文件的異或運(yùn)算
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)兩個(gè)文件的異或運(yùn)算,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-07-07
5分鐘搭建SpringCloud Eureka服務(wù)注冊(cè)中心的實(shí)現(xiàn)
這篇文章主要介紹了5分鐘搭建SpringCloud Eureka服務(wù)注冊(cè)中心的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03
Spring Boot Starter 的應(yīng)用場(chǎng)景與自動(dòng)配置方式
本文介紹了Spring Boot Starter的使用場(chǎng)景,如何自定義Starter以及Spring Boot自動(dòng)配置原理,Spring Boot Starter解決了依賴導(dǎo)入和配置繁瑣的問題,通過自動(dòng)配置類和xxxProperties類實(shí)現(xiàn)組件的自動(dòng)注入和配置,感興趣的朋友一起看看吧2025-03-03

