SpringBoot多数据源解决方案
SpringBoot多数据源解决方案
Java大哥大 2018-12-28 16:14:51
近在做一个数据统计的项目,这里涉及到多个数据库的数据统计,所以找到了一个不错的解决方案。
写一篇博客作为笔记。
例子介绍
类库:例子中使用的是MyBatis Plus和Dynamic Datasource的组合
Maven配置示例
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.0.6</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>2.4.2</version>
</dependency>
配置文件
这里的配置使用的是yml文件,主要的配置就是datasource,别的配置都是陪衬。
配置文件示例:
server:
port: 2080
logging:
level:
cn.mrxionge.bootdemo: debug
org.springframework.web: debug
org.springframework.data: debug
mybatis-plus:
executor-type: simple
spring:
datasource:
#配置hikari连接池
hikari:
minimum-idle: 4
maximum-pool-size: 16
connection-timeout: 10000
idle-timeout: 30000
connection-init-sql: set names utf8mb4
#动态数据源配置
dynamic:
#主数据源
primary: a01
datasource:
#数据源a01
a01:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/a01?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: 123456
#数据源a02
a02:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/a02?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: 123456
#数据源a03
a03:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/a03?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: 123456
这里需要注意一个问题,就是primary配置是必填项,这个作为全局的默认数据源。
每个数据源可以是不同的机器上面的不同的服务器,例子中给的配置只是一个demo,所以是同一个MySQL实例的三个库而已,虽然简单,但是道理是一样的。
还有就是配置多数据源的时候,IDEA目前没有提示,自己多留意一下缩进就好了。
配置完成之后,我们可以通过启动程序看日志打印来查看是否配置成功。
日志示例:
中间红色方框的内容就是我们多数据源的加载信息。
添加测试数据
我们的示例比较简单,是三个不同的数据库中,三个同样结构的数据表,但是其中的数据不同。
数据库信息示例:
如图,我们在三个库中写入不同的数据,方便我们测试
动态数据源的简单实用
这里我们新建三个不用的Mapper文件,每个Mapper文件对应一个数据源,我们通过调用不同的Mapper文件中的方法来实现查询不同的数据库中的数据。
Mapper文件示例:
@DS(value = "a01")
@Mapper
public interface MapperA01 extends BaseMapper<UserInfo> {
@Select("SELECT * FROM user_info")
List<UserInfo> getAllUser();
}
@DS(value = "a02")
@Mapper
public interface MapperA02 extends BaseMapper<UserInfo> {
@Select("SELECT * FROM user_info")
List<UserInfo> getAllUser();
}
@DS(value = "a03")
@Mapper
public interface MapperA03 extends BaseMapper<UserInfo> {
@Select("SELECT * FROM user_info")
List<UserInfo> getAllUser();
}
这里我们创建了三个Mapper,每个Mapper文件上面都有一个“@DS”注解,这个注解就是指定这个Mapper接口里面的所有的方法都使用注解里面所配置的数据源。当然,DS注解的使用方法非常灵活,这里制作一个简单的例子,给出一个思路,方便理解和入门,详细的使用,请参考他们的官方文档。
测试阶段
这里我们再写一个业务层和控制层,来测试我们的多数据源查询方法。
@Service
public class AppService {
@Autowired
private MapperA01 mapperA01;
@Autowired
private MapperA02 mapperA02;
@Autowired
private MapperA03 mapperA03;
/**
* 查询A01库中的数据
*
* @return 用户信息列表
*/
List<UserInfo> getUser01() {
return mapperA01.getAllUser();
}
/**
* 查询A02库中的数据
*
* @return 用户信息列表
*/
List<UserInfo> getUser02() {
return mapperA02.getAllUser();
}
/**
* 查询A03库中的数据
*
* @return 用户信息列表
*/
List<UserInfo> getUser03() {
return mapperA03.getAllUser();
}
}
@RestController
public class AppHandler {
@Autowired
private AppService service;
@GetMapping(path = "/get01")
public Mono get01() {
//查询A01数据
return Mono.fromSupplier(service::getUser01);
}
@GetMapping(path = "/get02")
public Mono get02() {
//查询A02数据
return Mono.fromSupplier(service::getUser02);
}
@GetMapping(path = "/get03")
public Mono get03() {
//查询A03数据
return Mono.fromSupplier(service::getUser03);
}
}
调用URL进行测试:
测试完成,是我们想要的结果。
结尾
以上的例子很简单,但并不意味着Dynamic Datasource的功能只有这些,详细的使用请大家去看这个项目的文档,结合自身的业务场景来选择一个最优的解决档案。当然,Dynamic Datasource应该是我使用中最简单最快捷最方便的多数据源解决方案
如果你使用的不是MyBatis Plus,而是MyBatis。嗯……答案是,没有任何问题!