1、导入pom.xml当前最新版本为3.5.0
当前版本中使用发生的问题 项目启动之后@DS("master") 和@DS("slave") 来回切换 jrebel热部署不生效 必须重启项目
<!-- https://mvnrepository.com/artifact/com.baomidou/dynamic-datasource-spring-boot-starter -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>3.5.0</version>
</dependency>
2、选择三个数据库创建表分别是master、slave_1、slave_2
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(20) DEFAULT NULL,
`sex` varchar(6) DEFAULT NULL,
`birthday` date DEFAULT NULL,
`address` varchar(20) DEFAULT NULL,
`password` varchar(20) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
-- 主库运行
INSERT INTO `user`(`id`, `username`, `sex`, `birthday`, `address`, `password`) VALUES (1, 'master', '男', '2022-01-26', '上海', '123456');
-- 从库1运行
INSERT INTO `user`(`id`, `username`, `sex`, `birthday`, `address`, `password`) VALUES (1, 'slave_1', '男', '2022-01-26', '上海', '123456');
-- 从库2运行
INSERT INTO `user`(`id`, `username`, `sex`, `birthday`, `address`, `password`) VALUES (1, 'slave_2', '男', '2022-01-26', '上海', '123456');
2、yml配置
#sql日志打印包路径扫描到dao层即可
logging:
level:
com.ljy.dynamicdatasource.dao: debug
#mybatis-plus配置
mybatis-plus:
type-aliases-package: com.lezu.springboot.dto
mapper-locations: classpath:mapper/*.xml
global-config:
db-config:
logic-delete-value: 1
logic-not-delete-value: 0
#mysql库########################start###############################
spring:
datasource:
dynamic:
#设置默认的数据源或者数据源组,默认值即为master
primary: master
#严格匹配数据源,默认false. true未匹配到指定数据源时抛异常,false使用默认数据源
strict: false
datasource:
master:
url: jdbc:mysql://localhost:3306/lezu?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useSSL=false&allowMultiQueries=true&rewriteBatchedStatements=true
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver # 3.2.0开始支持SPI可省略此配置
slave_1:
url: jdbc:mysql://localhost:3306/test1?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useSSL=false
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
slave_2:
url: jdbc:mysql://localhost:3306/test2?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useSSL=false
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
3、使用@DS注解来完成多数据源的配置
这里我就简化的写一下了
controller
@RestController
@RequestMapping("user")
public class UserController {
/**
* 服务对象
*/
@Resource
private UserService userService;
/**
* slave从库查询数据
* 调用地址: http://localhost:8080/user/queryById/1
*/
@GetMapping("queryById/{id}")
public ResponseEntity<User> queryById(@PathVariable("id") Integer id) {
System.out.println("当前配置为slave从库");
System.out.println("当前配置为slave从库");
System.out.println("当前配置为slave从库");
return ResponseEntity.ok(this.userService.queryById(id));
}
/**
* master主库写入数据
* 调用地址: http://localhost:8080/user/add
*/
@GetMapping("add")
public ResponseEntity<User> add(User user) {
System.out.println("当前配置为master主库");
System.out.println("当前配置为master主库");
System.out.println("当前配置为master主库");
user.setAddress("上海");
user.setBirthday(new Date());
user.setPassword("123");
user.setUsername("master");
user.setSex("system");
return ResponseEntity.ok(this.userService.insert(user));
}
}
Service
注意看PS后面这句话很重要能达到数据库层面负载均衡的效果
当然你也可以指定配置slave_1或者slave_2
/**
* slave从库查询数据
* PS:当配置文件中有多个slave_开头的可以配置简化为slave自动使用轮询的方式去调用slave_1和slave_2 #该注解也可以使用在类名上
*/
@DS("slave")
@Override
public User queryById(Integer id) {
return this.userDao.queryById(id);
}
/**
* master主库写入数据
*/
//@DS("master") //和YML中配置的数据源名称对应 如果该注解不写默认使用master
@Override
public User insert(User user) {
this.userDao.insert(user);
return user;
}
master添加数据
slave查询数据(查询带负载均衡轮询效果)
4、事务的回滚的使用(同时操作master和slave的insert操作 然后抛出异常)
controller
/**
* 测试master主库和slave一起写入数据事务回滚
* 调用地址: http://localhost:8080/user/add
*/
@DSTransactional //本组件集成了alibaba分布式事务组件seata
@GetMapping("add")
public String add(User user) {
user.setAddress("上海");
user.setBirthday(new Date());
user.setPassword("123");
user.setUsername("masterAndSlave");
user.setSex("system");
this.userService.master(user);
this.userService.slave(user);
int i = 2 / 0; //自定义抛出异常来测试是否回滚
return "SUCCESS";
}
Service
/**
* master主库写入数据测试
*/
@DS("master") //和YML中配置的数据源名称对应 如果该注解不写默认使用master
@Override
public User master(User user) {
this.userDao.insert(user);
return user;
}
/**
* slave_1从库写入数据测试
*/
@DS("slave_1")
@Override
public User slave(User user) {
this.userDao.insert(user);
return user;
}
Gitee官方文档:https://gitee.com/baomidou/dynamic-datasource-spring-boot-starter
GitHub官方文档:https://github.com/baomidou/dynamic-datasource-spring-boot-starter