springboot+druid+mybatis plus的多資料來源配置
多資料來源配置,在我們整合多個系統或者對接的時候經常會用到,結合springboot、druid提供了比較方便的整合方案。
思路:
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
db3:
url: jdbc:oracle:thin:@192.168.136.223:ORCL
username: sb
password: sb123456
driver-class-name: oracle.jdbc.OracleDriver
initialSize: 5
minIdle: 5
maxActive: 20
2、啟動載入多個資料來源
下面mybatis plus的全域性配置被注掉了,因為同樣可以在yml中配置也可以
package com.df.openapi.config;
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import com.baomidou.mybatisplus.MybatisConfiguration;
import com.baomidou.mybatisplus.entity.GlobalConfiguration;
import com.baomidou.mybatisplus.mapper.LogicSqlInjector;
import com.baomidou.mybatisplus.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean;
import com.df.openapi.config.db.DBTypeEnum;
import com.df.openapi.config.db.DynamicDataSource;
import com.df.openapi.config.db.MyMetaObjectHandler;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.type.JdbcType;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
/**
* @author 小塵哥
*/
@EnableTransactionManagement
@Configuration
@MapperScan("com.df.openapi.**.mapper.db*")
public class MybatisPlusConfig {
@Bean
public PaginationInterceptor paginationInterceptor() {
PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
paginationInterceptor.setLocalPage(true);
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();
}
@Bean(name = "db3")
@ConfigurationProperties(prefix = "spring.datasource.druid.db3")
public DataSource db3() {
return DruidDataSourceBuilder.create().build();
}
/**
* 動態資料來源配置
*
* @return
*/
@Bean
@Primary
public DataSource multipleDataSource(@Qualifier("db1") DataSource db1,
@Qualifier("db2") DataSource db2,
@Qualifier("db3") DataSource db3) {
DynamicDataSource dynamicDataSource = new DynamicDataSource();
Map<Object, Object> targetDataSources = new HashMap<>();
targetDataSources.put(DBTypeEnum.db1.getValue(), db1);
targetDataSources.put(DBTypeEnum.db2.getValue(), db2);
targetDataSources.put(DBTypeEnum.db3.getValue(), db3);
dynamicDataSource.setTargetDataSources(targetDataSources);
dynamicDataSource.setDefaultTargetDataSource(db2);
return dynamicDataSource;
}
@Bean("sqlSessionFactory")
public SqlSessionFactory sqlSessionFactory() throws Exception {
MybatisSqlSessionFactoryBean sqlSessionFactory = new MybatisSqlSessionFactoryBean();
sqlSessionFactory.setDataSource(multipleDataSource(db1(), db2(),db3()));
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());
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"), db3("db3");
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 {
@Override
protected Object determineCurrentLookupKey() {
return DbContextHolder.getDbType();
}
}
5、設定、獲取資料來源
package com.df.openapi.config.db;
public class DbContextHolder {
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設定的足夠小是為了讓他先執行
package com.df.openapi.config.db;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
/**
* @author 迪富
*/
@Component
@Order(value = -100)
@Slf4j
@Aspect
public class DataSourceSwitchAspect {
@Pointcut("execution(* com.df.openapi.*.mapper.db1..*.*(..))")
private void db1Aspect() {
}
@Pointcut("execution(* com.df.openapi.*.mapper.db2..*.*(..))")
private void db2Aspect() {
}
@Pointcut("execution(* com.df.openapi.*.mapper.db3..*.*(..))")
private void db3Aspect() {
}
@Before("db1Aspect()")
public void db1() {
log.info("切換到db1 資料來源...");
DbContextHolder.setDbType(DBTypeEnum.db1);
}
@Before("db2Aspect()")
public void db2() {
log.info("切換到db2 資料來源...");
DbContextHolder.setDbType(DBTypeEnum.db2);
}
@Before("db3Aspect()")
public void db3() {
log.info("切換到db3 資料來源...");
DbContextHolder.setDbType(DBTypeEnum.db3);
}
}
7、mapper層結構
8、寫一個service測試一下
可以看到下面的兩個Mapper分別來自db1和db2
package com.df.openapi.system.service.impl;
import com.df.openapi.system.entity.PtDict;
import com.df.openapi.system.entity.SysDict;
import com.df.openapi.system.mapper.db1.PtDictMapper;
import com.df.openapi.system.mapper.db2.SysDictMapper;
import com.df.openapi.system.service.IDictService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@Service
public class DictServiceImpl implements IDictService {
@Resource
private PtDictMapper ptDictMapper;
@Resource
private SysDictMapper sysDictMapper;
@Override
public void getById(String id) {
PtDict dict = ptDictMapper.selectById("2bf6257fc8fe483c84c1ad7e89d632f6");
SysDict sysDict = sysDictMapper.getById("49");
System.out.println("123");
}
}
9、簡單的單元測試
@RunWith(SpringRunner.class)
@SpringBootTest
public class OpenApiApplicationTests {
@Autowired
private IDictService dictService;
@Test
public void contextLoads() {
}
@Test
public void test() {
dictService.getById("1");
}
}
10、測試結果
參考上面的方法,可以隨意配置三四五六七八九十個資料來源都沒問題,有問題歡迎隨時來撩!
相關文章
- SpirngBoot整合Mybatis Plus多資料來源bootMyBatis
- 多資料來源配置
- SpringBoot 的多資料來源配置Spring Boot
- 多資料來源結合mybatis-plus的使用MyBatis
- SpringBoot配置多資料來源Spring Boot
- springBoot 多資料來源配置Spring Boot
- springboot多資料來源配置Spring Boot
- MyBatis配置多資料來源MyBatis
- web 配置多資料來源Web
- Spring多資料來源配置Spring
- Spring Boot 配置多資料來源Spring Boot
- Spring Boot 多資料來源配置Spring Boot
- SpringBoot 配置多資料來源 MyBatisSpring BootMyBatis
- SpringBoot整合MyBatis-Plus實現多資料來源操作Spring BootMyBatis
- Spring-Boot 多資料來源配置+動態資料來源切換+多資料來源事物配置實現主從資料庫儲存分離Springboot資料庫
- Springboot 配置多資料來源Mybatis的UnderScore不生效Spring BootMyBatis
- 使用Spring Boot配置多個資料來源 - UdithSpring Boot
- Spring boot 如何快速的配置多個 Redis 資料來源Spring BootRedis
- 多資料來源與動態資料來源的權衡
- springboot 配置多個資料來源,@MapperScan方式繫結Spring BootAPP
- Springboot 多資料來源配置,結合tk-mybatisSpring BootMyBatis
- 【教程】Spring+Mybatis環境配置多資料來源SpringMyBatis
- MyBatis-Plus:建立動態資料來源MyBatis
- SpringBoot多資料來源Spring Boot
- 如何用hutool-db實現多資料來源配置
- 全程解析,MyBatis在SpringBoot中的動態多資料來源配置MyBatisSpring Boot
- 基於SpirngBoot2.0+ 的 SpringBoot+Mybatis 多資料來源配置Spring BootMyBatis
- SpringBoot | 3.1 配置資料來源Spring Boot
- weblogic GridLink資料來源配置Web
- weblogic配置JDBC資料來源WebJDBC
- springboot 配置DRUID資料來源的方法Spring BootUI
- Spring系列 之資料來源的配置 資料庫 資料來源 連線池的區別Spring資料庫
- Spring Boot 2.x基礎教程:MyBatis的多資料來源配置Spring BootMyBatis
- 談一談Spring-Mybatis在多資料來源配置上的坑SpringMyBatis
- 談一談 Spring-Mybatis 在多資料來源配置上的坑SpringMyBatis
- springboot 2 Hikari 多資料來源配置問題(dataSourceClassName or jdbcUrl is required)Spring BootJDBCUI
- 資料來源(DataSource)是什麼以及SpringBoot中資料來源配置Spring Boot
- 【Database】可選的資料來源配置項Database