首页 > 解决方案 > MyBatis中使用两个数据源时切换SqlSessionTemplate的自定义注解

问题描述

我目前正在使用带有多个数据源的 Spring Boot 2.5 和 MyBatis 设置。

我想使用在我的映射器接口中命名的自定义方法级注释@ReadReplica,并让 MyBatis 切换到我的第二个数据源(readReplicaDataSource)。

像这样的东西:

@Mapper
public interface MyMapper {

    @ReadReplica // uses readReplicaDataSource
    List<MyData> selectAll();

    int insert(MyData record); // uses primaryDataSource
}
    

这可能吗?


应用程序.yaml

spring:
    datasource:
        driver-class-name: org.postgresql.Driver
        password: ${DB_PSWD}
        username: ${DB_USER}
        jdbc-url: ${DB_URL}
    datasource-read-replica:
        driver-class-name: org.postgresql.Driver
        password: ${DB_PSWD}
        username: ${DB_USER}
        jdbc-url: ${DB_READ_REPLICA_URL}

mybatis:
    mapper-locations: mapper/*.xml

构建.gradle

implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:2.1.4'
implementation 'org.mybatis.dynamic-sql:mybatis-dynamic-sql:1.3.0'

PrimaryMyBatisConfig.java

@Configuration
@Slf4j
public class PrimaryMyBatisConfig {
   
    @Value("${mybatis.mapper-locations}")
    private String mapperLocations;
  
    @Primary
    @Bean(name="primaryDataSource")
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource dataSource() {
        return DataSourceBuilder.create().build();
    }

    SqlSessionFactory primarySqlSessionFactory(DataSource dataSource) {
        SqlSessionFactory sessionFactory = null;
        try {
            SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
            bean.setDataSource(dataSource);
            bean.setMapperLocations((new PathMatchingResourcePatternResolver().getResources(ResourceLoader.CLASSPATH_URL_PREFIX + mapperLocations)));
            sessionFactory = bean.getObject();
        } catch (Exception e) {
            log.error("Error establishing primary SQL session factory {}", e);
        }
        return sessionFactory;
    }

    @Bean
    @Primary
    SqlSessionTemplate primarySqlSessionTemplate(@Qualifier("primaryDataSource") DataSource dataSource) {
        return new SqlSessionTemplate(primarySqlSessionFactory(dataSource));
    }
    
    @Bean
    @Primary
    public DataSourceTransactionManager primaryTransactionManager(@Qualifier("primaryDataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }
}

ReadReplicaMyBatisConfig.java

@Configuration
@Slf4j
public class ReadReplicaMyBatisConfig {
   
    @Value("${mybatis.mapper-locations}")
    private String mapperLocations;
  
    @Bean(name="readReplicaDataSource")
    @ConfigurationProperties(prefix = "spring.datasource-read-replica")
    public DataSource dataSource() {
        return DataSourceBuilder.create().build();
    }
    
    SqlSessionFactory readReplicaSqlSessionFactory(DataSource dataSource) {
        SqlSessionFactory sessionFactory = null;
        try {
            SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
            bean.setDataSource(dataSource);
            bean.setMapperLocations((new PathMatchingResourcePatternResolver().getResources(ResourceLoader.CLASSPATH_URL_PREFIX + mapperLocations)));
            sessionFactory = bean.getObject();
        } catch (Exception e) {
            log.error("Error establishing read replica SQL session factory {}", e);
        }
        return sessionFactory;
    }

    @Bean
    SqlSessionTemplate readReplicaSqlSessionTemplate(@Qualifier("readReplicaDataSource") DataSource dataSource) {
        return new SqlSessionTemplate(readReplicaSqlSessionFactory(dataSource));
    }
    
    @Bean
    public DataSourceTransactionManager readReplicaTransactionManager(@Qualifier("readReplicaDataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }
}

ReadReplica.java

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface ReadReplica {}

标签: spring-bootmybatisspring-mybatis

解决方案


您应该能够通过配置自定义@MapperScan注释来完成此操作。这是一个将不同包中的映射器连接到不同模板的示例。连接到不同数据源的概念类似:https ://github.com/jeffgbutler/mybatis-cockroach-demo/blob/master/src/main/java/com/example/cockroachdemo/MyBatisConfiguration.java


推荐阅读