springboot + mybatis 多数据源切换

参考的b站博主写的
配置文件:

spring:
  datasource:
    db1:
      jdbc-url: jdbc:mysql://localhost:3306/interview_database?useUnicode=true&characterEncoding=utf-8&useSSL=false
      username: root
      password: 12345
      driver-class-name: com.mysql.cj.jdbc.Driver
    db2:
      jdbc-url: jdbc:mysql://localhost:3306/cailu-family-manager?useUnicode=true&characterEncoding=utf-8&useSSL=false
      username: root
      password: 12345
      driver-class-name: com.mysql.cj.jdbc.Driver

DataSourceChange.java 设定切换数据库的类,使用ThreadLocal


/**
 * @author HFQ
 * @version 1.0.0
 * @ClassName DataSourceChange.java
 * @Description 数据源切换
 * @createTime 2024年07月03日 22:56:00
 */
public class DataSourceChange {
    private static final ThreadLocal<String> contextHolder = new ThreadLocal();
    // 设置默认数据库
    static {
        contextHolder.set("db1");
    }
    public static void setDB(String dbType){
        contextHolder.set(dbType);
    }
    public static String getDB(){
        return contextHolder.get();
    }
}

DynamicDataSource 类设置数据源,继承AbstractRoutingDataSource类基于查找键将getConnection()调用路由到各种目标DataSource之一的抽象DataSource实现。后者通常(但不一定)是通过一些线程绑定的事务上下文来确定的。

/**
 * @author HFQ
 * @version 1.0.0
 * @ClassName DynamicDataSource.java
 * @Description 设置数据源
 * @createTime 2024年07月03日 22:51:00
 */
public class DynamicDataSource extends AbstractRoutingDataSource {
    @Override
    protected Object determineCurrentLookupKey() {
        return DataSourceChange.getDB();
    }
}

DataSourceConfig类多数据源配置

/**
 * @author HFQ
 * @version 1.0.0
 * @ClassName DataSourceConfig.java
 * @Description 多数据源配置
 * @createTime 2024年07月03日 21:57:00
 */
@Configuration
public class DataSourceConfig {

    /**
     * @ConfigurationProperties用的反射来做这个功能
     * @return
     */
    @Bean(name = "db1")
    @ConfigurationProperties(prefix = "spring.datasource.db1")
    public DataSource db1(){
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "db2")
    @ConfigurationProperties(prefix = "spring.datasource.db2")
    public DataSource db2(){
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "dynamicDataSource")
    @Primary
    public DataSource dynamicDataSource(@Qualifier("db1")DataSource db1,@Qualifier("db2")DataSource db2){
        DynamicDataSource dynamicDataSource = new DynamicDataSource();
        // 设置默认数据源 这个代码有点重复了,因为我们在DataSourceChange类中已经设定了默认数据库
        dynamicDataSource.setDefaultTargetDataSource(db1);
        HashMap<Object, Object> objectObjectHashMap = new HashMap<>();
        objectObjectHashMap.put("db1", db1);
        objectObjectHashMap.put("db2", db2);
        dynamicDataSource.setTargetDataSources(objectObjectHashMap);
        return dynamicDataSource;
    }

    @Bean
    public PlatformTransactionManager transactionManager(@Qualifier("dynamicDataSource") DataSource dynamicDataSource){
        return new DataSourceTransactionManager(dynamicDataSource);
    }
}

@ConfigurationProperties(prefix = “spring.datasource.db1”)
在Spring Boot中,@ConfigurationProperties注解用于将外部的配置属性(如application.yml或application.properties文件中的属性)映射到一个Java类的字段中。当你创建DataSourceBuilder并调用build方法时,Spring Boot会自动注入这些配置属性(使用的反射完成)。

测试一下
测试代码:

@Test
    public void testDb1(){
    // tagsMapper使用的是db1的连接,testMapper使用的是db2连接
        ArrayList<String> strings = new ArrayList<>();
        strings.add("女性");
        strings.add("广州");
        for (Integer tagsByName : tagsMapper.findTagsByNames(strings)) {
            System.out.println(tagsByName);
        }
        // 切换到db2
        DataSourceChange.setDB("db2");
        List<Map<String, Object>> maps = testMapper.selectTest();
        for (Map<String, Object> map : maps) {
            System.out.println(map.get("account_name").toString());
        }
    }

然后, 既然是多数据源,那mapper.xml文件也需要分层
所以我的mapper文件夹是这样的
在这里插入图片描述
mapper-locations 使用逗号分隔
yml配置文件:

mybatis:
  mapper-locations: classpath*:/mapper/db1/*.xml,classpath*:/mapper/db2/*.xml

执行结果:
在这里插入图片描述

上一篇:B+树的元素检索过程


下一篇:机器学习——逻辑回归