SpringBoot MyBatyisPlus 多数据源切换
- 实现功能为通 aop 控制不同包下面的类采用不同的数据库
- 在
mapper.one包中的数据库采用one_db - 在
mapper.two包总的数据库采用two_db
- 在
导入相关依赖
<dependency><groupId>com.baomidougroupId><artifactId>mybatis-plus-boot-starterartifactId><version>3.2.0version>
dependency>
<dependency><groupId>com.alibabagroupId><artifactId>druid-spring-boot-starterartifactId><version>1.1.21version>
dependency>
<dependency><groupId>org.springframework.bootgroupId><artifactId>spring-boot-starter-aopartifactId>
dependency>
<dependency><groupId>org.projectlombokgroupId><artifactId>lombokartifactId><optional>trueoptional>
dependency>
<dependency><groupId>org.springframework.bootgroupId><artifactId>spring-boot-starter-webartifactId>
dependency>
在配置文件中配置数据源
##onedb
spring.datasource.druid.one.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.druid.one.url=jdbc:mysql://localhost:3306/db_one?characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8
spring.datasource.druid.one.username=username
spring.datasource.druid.one.password=password##twodb
spring.datasource.druid.two.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.druid.two.url=jdbc:mysql://localhost:3306/db_two?characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8
spring.datasource.druid.two.username=username
spring.datasource.druid.two.password=password
配置 MyBatisPlus 相关
mybatis-plus:mapper-locations: classpath:/mapper/**/*Mapper.xmltypeAliasesPackage: com.sec.datasource.*.domainglobal-config:refresh: truedb-config:id-type: autofield-strategy: ignoredcapital-mode: truelogic-delete-value: 1logic-not-delete-value: 0db-type: mysqlconfiguration:map-underscore-to-camel-case: truecache-enabled: falsejdbc-type-for-null: 'null'
在
config包下配置 MyBatisPlus 数据源
@Configuration
@MapperScan("com.sec.datasource.datasource.mapper")
public class MyBatiesPlusConfiguration {@Bean(name = "one")@ConfigurationProperties(prefix = "spring.datasource.druid.one" )public DataSource one() {return DruidDataSourceBuilder.create().build();}@Bean(name = "two")@ConfigurationProperties(prefix = "spring.datasource.druid.two" )public DataSource two() {return DruidDataSourceBuilder.create().build();}/*** 动态数据源配置* @return*/@Bean@Primarypublic DataSource multipleDataSource(@Qualifier("one") DataSource onedb, @Qualifier("two") DataSource twodb) {MultipleDataSource multipleDataSource = new MultipleDataSource();Map< Object, Object > targetDataSources = new HashMap<>();targetDataSources.put(DataSourceEnum.ONE_DB.getValue(), onedb);targetDataSources.put(DataSourceEnum.TWO_DB.getValue(), twodb);//添加数据源multipleDataSource.setTargetDataSources(targetDataSources);//设置默认数据源multipleDataSource.setDefaultTargetDataSource(onedb);return multipleDataSource;}@Bean("sqlSessionFactory")public SqlSessionFactory sqlSessionFactory() throws Exception {MybatisSqlSessionFactoryBean sqlSessionFactory = new MybatisSqlSessionFactoryBean();sqlSessionFactory.setDataSource(multipleDataSource(one(), two()));MybatisConfiguration configuration = new MybatisConfiguration();configuration.setJdbcTypeForNull(JdbcType.NULL);configuration.setMapUnderscoreToCamelCase(true);configuration.setCacheEnabled(false);sqlSessionFactory.setConfiguration(configuration);return sqlSessionFactory.getObject();}}
其他辅助类
public class DataSourceContextHolder {private static final ThreadLocal<String> contextHolder = new InheritableThreadLocal<>();public static void setDataSource(DataSourceEnum db){contextHolder.set(db.getValue());}public static String getDataSource(){return contextHolder.get();}public static void clear(){contextHolder.remove();}}
public class MultipleDataSource extends AbstractRoutingDataSource {@Overrideprotected Object determineCurrentLookupKey() {return DataSourceContextHolder.getDataSource();}}
将已有数据库定义成枚举方便调用
@Getter
public enum DataSourceEnum {ONE_DB("one_db"),TWO_DB("two_db");private String value;DataSourceEnum(String value){this.value=value;}}
编写 aop 逻辑进行数据源切换
@Slf4j
@Aspect
@Order(-1)
@Component
public class DataSourceAspect {@Pointcut("execution(* com.sec.datasource.datasource.mapper.onedb.*.*(..))")private void onedbAspect() {}@Pointcut("execution(* com.sec.datasource.datasource.mapper.twodb.*.*(..))")private void twodbAspect() {}@Before("onedbAspect()")public void onedb() {log.info("select to datasource one");DataSourceContextHolder.setDataSource(DataSourceEnum.ONE_DB);}@Before("twodbAspect()")public void twodb() {log.info("select to datasource two");DataSourceContextHolder.setDataSource(DataSourceEnum.TWO_DB);}@After("onedbAspect() || twodbAspect()")public void doAfter(){DataSourceContextHolder.clear();}}
下面就是在 mapper 包中编写逻辑 controller 调用测试了

Demo 在我的 Gitee 中可以看得到
https://gitee.com/jiangruyi/many-datasource.git
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
