大家好,欢迎来到IT知识分享网。
SpringBoot项目中常见的多数据源管理
一、简介
微服务架构下,数据库常常随着业务拆分会分为多个库。一般涉及不同数据库的查询都是通过微服务间的调用实现,但是例如生成报表和管理后台的业务为了方便一般会给一个微服务配置多个数据源。那么项目中常用的多数据源方案有三种。
二、方案介绍
方案一:使用Spring提供的AbstractRoutingDataSource
spring: datasource: type: com.alibaba.druid.pool.DruidDataSource datasource1: url: jdbc:mysql://127.0.0.1:3306/datasource1?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF8&useSSL=false username: root password: root initial-size: 1 min-idle: 1 max-active: 20 test-on-borrow: true driver-class-name: com.mysql.cj.jdbc.Driver datasource2: url: jdbc:mysql://127.0.0.1:3306/datasource2?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF8&useSSL=false username: root password: root initial-size: 1 min-idle: 1 max-active: 20 test-on-borrow: true driver-class-name: com.mysql.cj.jdbc.Driver
2.配置类
@Configuration public class DataSourceConfig {
@Bean @ConfigurationProperties(prefix = "spring.datasource.datasource1") public DataSource dataSource1() {
// 底层会自动拿到spring.datasource中的配置, 创建一个DruidDataSource return DruidDataSourceBuilder.create().build(); } @Bean @ConfigurationProperties(prefix = "spring.datasource.datasource2") public DataSource dataSource2() {
// 底层会自动拿到spring.datasource中的配置, 创建一个DruidDataSource return DruidDataSourceBuilder.create().build(); } @Bean public DataSourceTransactionManager transactionManager1(DynamicDataSource dataSource){
DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager(); dataSourceTransactionManager.setDataSource(dataSource); return dataSourceTransactionManager; } @Bean public DataSourceTransactionManager transactionManager2(DynamicDataSource dataSource){
DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager(); dataSourceTransactionManager.setDataSource(dataSource); return dataSourceTransactionManager; } }
DataSourceConfig 主要做了两件事:
- 利用springboot的ConfigurationProperties注解,达到自动解析配置中的两个数据源,并且生成bean.
- 配置DataSourceTransactionManager
3.实现类
@Component @Primary // 将该Bean设置为主要注入Bean public class DynamicDataSource extends AbstractRoutingDataSource {
// 当前使用的数据源标识 public static ThreadLocal<String> name=new ThreadLocal<>(); // 写 @Autowired DataSource dataSource1; // 读 @Autowired DataSource dataSource2; // 返回当前数据源标识 @Override protected Object determineCurrentLookupKey() {
return name.get(); } @Override public void afterPropertiesSet() {
// 为targetDataSources初始化所有数据源 Map<Object, Object> targetDataSources=new HashMap<>(); targetDataSources.put("W",dataSource1); targetDataSources.put("R",dataSource2); super.setTargetDataSources(targetDataSources); // 为defaultTargetDataSource 设置默认的数据源 super.setDefaultTargetDataSource(dataSource1); super.afterPropertiesSet(); } }
4.具体的业务方法(部分代码)
@Override // @WR("W") // 写操作 public void save(Hello hello) {
DynamicDataSource.name.set("W"); helloMapper.save(hello); }
主要是在执行真正的方法前,通过key来路由到不同的数据源,这个实现也可以通过切面方式实现。
方案二:使用MyBatis注册多个SqlSessionFactory
spring: datasource: type: com.alibaba.druid.pool.DruidDataSource datasource1: url: jdbc:mysql://127.0.0.1:3306/datasource1?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF8&useSSL=false username: root password: root initial-size: 1 min-idle: 1 max-active: 20 test-on-borrow: true driver-class-name: com.mysql.cj.jdbc.Driver datasource2: url: jdbc:mysql://127.0.0.1:3306/datasource2?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF8&useSSL=false username: root password: root initial-size: 1 min-idle: 1 max-active: 20 test-on-borrow: true driver-class-name: com.mysql.cj.jdbc.Driver
2.多数据源配置
@Configuration // 配置不同包路径下的mapper使用不同的数据源 @MapperScan(basePackages = "com.xwl.datasource.dynamic.mybatis.mapper.write", sqlSessionFactoryRef="wSqlSessionFactory") public class WMyBatisConfig {
@Bean @ConfigurationProperties(prefix = "spring.datasource.datasource1") public DataSource dataSource1() {
// 底层会自动拿到spring.datasource中的配置, 创建一个DruidDataSource return DruidDataSourceBuilder.create().build(); } @Bean @Primary public SqlSessionFactory wSqlSessionFactory() throws Exception {
final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean(); // 指定主库 sessionFactory.setDataSource(dataSource1()); return sessionFactory.getObject(); } @Bean public DataSourceTransactionManager wTransactionManager(){
DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager(); dataSourceTransactionManager.setDataSource(dataSource1()); return dataSourceTransactionManager; } @Bean public TransactionTemplate wTransactionTemplate(){
return new TransactionTemplate(wTransactionManager()); } }
@Configuration // 配置不同包路径下的mapper使用不同的数据源 @MapperScan(basePackages = "com.xwl.datasource.dynamic.mybatis.mapper.read", sqlSessionFactoryRef="rSqlSessionFactory") public class RMyBatisConfig {
@Bean @ConfigurationProperties(prefix = "spring.datasource.datasource2") public DataSource dataSource2() {
// 底层会自动拿到spring.datasource中的配置, 创建一个DruidDataSource return DruidDataSourceBuilder.create().build(); } @Bean @Primary public SqlSessionFactory rSqlSessionFactory() throws Exception {
final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean(); // 指定主库 sessionFactory.setDataSource(dataSource2()); return sessionFactory.getObject(); } @Bean public DataSourceTransactionManager rTransactionManager(){
DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager(); dataSourceTransactionManager.setDataSource(dataSource2()); return dataSourceTransactionManager; } @Bean public TransactionTemplate rTransactionTemplate(){
return new TransactionTemplate(rTransactionManager()); } }
方案三:使用dynamic-datasource框架
<dependency> <groupId>com.baomidou</groupId> <artifactId>dynamic-datasource-spring-boot-starter</artifactId> <version>3.5.0</version> </dependency>
2.配置
spring: datasource: dynamic: #设置默认的数据源或者数据源组,默认值即为master primary: master #严格匹配数据源,默认false. true未匹配到指定数据源时抛异常,false使用默认数据源 strict: false datasource: master: url: jdbc:mysql://127.0.0.1:3306/datasource1?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF8&useSSL=false username: root password: root initial-size: 1 min-idle: 1 max-active: 20 test-on-borrow: true driver-class-name: com.mysql.cj.jdbc.Driver slave: url: jdbc:mysql://127.0.0.1:3306/datasource2?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF8&useSSL=false username: root password: root initial-size: 1 min-idle: 1 max-active: 20 test-on-borrow: true driver-class-name: com.mysql.cj.jdbc.Driver
3.具体的业务方法
@Override @DS("master") public void save(Hello hello) {
helloMapper.save(hello); }
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/116546.html