spring-boot - 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 {}
解决方案
您应该能够通过配置自定义@MapperScan
注释来完成此操作。这是一个将不同包中的映射器连接到不同模板的示例。连接到不同数据源的概念类似:https ://github.com/jeffgbutler/mybatis-cockroach-demo/blob/master/src/main/java/com/example/cockroachdemo/MyBatisConfiguration.java
推荐阅读
- python - Django CMS - 结构模式没有滚动条
- linux - Linux Jenkins测试文件是否存在于Windows共享中
- scenekit - 如何在 Scenekit 中为关键帧动画选择关键路径?
- excel - 使用列中的选择器在顶行中查找
- .net - RNGCryptoServiceProvider for 3DES and AES keys
- angular6 - 角管误差指数
- angular - 使用 ngx-charts 为特定系列自定义颜色
- javascript - 为什么在 .js 文件与 .vue 文件中使用时,我的项目中的 vuetify 会中断
- javascript - 是否可以通过 Node.js 后端隐藏 React 组件源代码?
- android - Web3J - 创建轻钱包的时间太长