这里列举了三种读写分离实现方案,分别是如下三种
1:MybatisPlus(读写分离)
1.1:首先创建三个数据库1主2从
表名是user表
1.2:代码实例
1:导入pom
<!--MybatisPlus的jar 3.0基于jdk8-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.3.1</version>
</dependency>
<!-- mybatisPlus多数据源依赖 实现读写分离-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>3.6.1</version>
</dependency>
<!-- mysql的依赖-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency>
<!--直接使用druid的starter 连接池-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.16</version>
</dependency>
2:配置spring的主从
server:
port: 8082
spring:
datasource:
dynamic:
primary: master #设置默认的数据源或者数据源组,默认值即为master
strict: false #严格匹配数据源,默认false. true未匹配到指定数据源时抛异常,false使用默认数据源
datasource:
master:
url: jdbc:mysql://localhost:3306/W1?useUnicode=true&characterEncoding=utf-8&useSSL=false
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource #配置德鲁伊数据源
druid:
initial-size: 10 #连接池初始化大小
min-idle: 10 #最小空闲连接数
max-active: 20 #最大连接数
slave_1:
url: jdbc:mysql://localhost:3306/W1R1?useUnicode=true&characterEncoding=utf-8&useSSL=false
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource #配置德鲁伊数据源
druid:
initial-size: 10 #连接池初始化大小
min-idle: 10 #最小空闲连接数
max-active: 20 #最大连接数
slave_2:
url: jdbc:mysql://localhost:3306/W1R2?useUnicode=true&characterEncoding=utf-8&useSSL=false
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource #配置德鲁伊数据源
druid:
initial-size: 10 #连接池初始化大小
min-idle: 10 #最小空闲连接数
max-active: 20 #最大连接数
#......省略
#以上会配置一个默认库master,一个组slave下有两个子库slave_1,slave_2
3:代码实例 @DS("slave") 注解用来切换数据源
/**
* @description 针对表【User】的数据库操作Service实现
* @createDate 2023-11-01 17:17:57
*/
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService{
@Resource
UserMapper userMapper;
//多个从库 负载均衡轮训查询 也可以注解到类上
//@DS("slave")
@DS("slave")
public User selectRW_S(Integer id) {
return userMapper.selectById(id);
}
//主库查询数据
//@DS("master")
@DS("master")
public User selectRW_M(Integer id) {
return userMapper.selectById(id);
}
//无注解,不指定数据, 默认查询主库
@Override
public User selectRW(Integer id) {
return userMapper.selectById(id);
}
}
controller代码根据请求不同访问不同的数据源
@RestController
public class UserControllerRW {
@Resource
UserServiceImpl userService;
//查询主库 @DS("master")
@GetMapping(value = "selectRW1")
public User selectRW_M(@RequestParam(name = "id",required = true) Integer id){
User user = userService.selectRW_M(id);
System.out.println(user);
return user;
}
//查询从库 @DS("slave") 轮训查询
@GetMapping(value = "selectRW2")
public User selectRW_S(@RequestParam(name = "id",required = true) Integer id){
User user = userService.selectRW_S(id);
System.out.println(user);
return user;
}
//无注解,不指定数据, 默认查询主库
@GetMapping(value = "selectRW3")
public User selectRW(@RequestParam(name = "id",required = true) Integer id){
User user = userService.selectRW(id);
System.out.println(user);
return user;
}
}
查询结果截图
1.3:优缺点分析
dynamic-datasource的jar包的官方文档
基础必读(免费) · dynamic-datasource · 看云
本框架只做切换数据的事情,不限制你的具体操作,从库也可以增删改查,读写分离只是他的一个小功能,分库分表要自己实现
- 支持 数据源分组 ,适用于多种场景 纯粹多库 读写分离 一主多从 混合模式。
- 支持数据库敏感配置信息 加密(可自定义) ENC()。
- 支持每个数据库独立初始化表结构schema和数据库database。
- 支持无数据源启动,支持懒加载数据源(需要的时候再创建连接)。
- 支持 自定义注解 ,需继承DS(3.2.0+)。
- 提供并简化对Druid,HikariCp,BeeCp,Dbcp2的快速集成。
- 提供对Mybatis-Plus,Quartz,ShardingJdbc,P6sy,Jndi等组件的集成方案。
- 提供 自定义数据源来源 方案(如全从数据库加载)。
- 提供项目启动后 动态增加移除数据源 方案。
- 提供Mybatis环境下的 纯读写分离 方案。
- 提供使用 spel动态参数 解析数据源方案。内置spel,session,header,支持自定义。
- 支持 多层数据源嵌套切换 。(ServiceA >>> ServiceB >>> ServiceC)。
- 提供 基于seata的分布式事务方案 。
- 提供 本地多数据源事务方案。