上一篇文件通过docker部署了mysql主从数据库:
docker方式部署mysql主从架构_修理男爵的博客-CSDN博客
本文介绍下java代码中如何连接并使用mysql主从数据库,实现读写分离。
mybatis-plus | 持久层框架 |
---|---|
sharding-jdbc | shardingsphere核心三套件之一,定位为在客户端使用的插件。 可以实现读写分离,分库分表等功能。 |
shardingsphere简介
shardingsphere核心三套件为:sharding-jdbc、sharding-proxy、sharding-sidecar
目前比较重要的是 sharding-jdbc 和 sharding-proxy。其中 sharding-jdbc 用得比较多。
sharding-jdbc:是一个插件,以jar包形式提供服务,所以直接在客户端引入后使用就行了。
基本原理:它会改写你的SQL,然后再请求数据库,把结果进行归并,以此实现读写分离、分库分表等功能。文本使用的是 sharding-jdbc。
sharding-proxy:定位为一个中间件。可以理解为它伪装成了一个mysql数据库,客户端使用的时候,不连接实际的mysql了,转而去连接sharding-proxy。读写分离、分库分表的实现,交给sharding-proxy去做,客户端代码中无需关注。使用时需要单独部署。
引入maven依赖
<!-- mysql-connector -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.22</version>
</dependency>
<!-- mybatis-plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.1</version>
</dependency>
<!-- sharding-jdbc -->
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>sharding-jdbc-spring-boot-starter</artifactId>
<version>4.1.1</version>
</dependency>
其中,springboot 使用的 2.5.x 版本。
配置主从数据源
读写分离比较重要的就是主从数据源的配置,通过shardingsphere能很方便地实现:
spring:
shardingsphere:
# 数据源配置
datasource:
names: master,slave
master:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
jdbc-url: jdbc:mysql://127.0.0.1:3311/test?useUnicode=true&serverTimezone=Asia/Shanghai&characterEncoding=UTF-8
username: root
password: 123456
slave:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
jdbc-url: jdbc:mysql://127.0.0.1:3312/test?useUnicode=true&serverTimezone=Asia/Shanghai&characterEncoding=UTF-8
username: root
password: 123456
# 设置主从,轮询策略
masterslave:
name: masterslave
load-balance-algorithm-type: round_robin
master-data-source-name: master
slave-data-source-names: slave
# 打印SQL
props:
sql:
show: true
好了,到这里其实就结束了,已经可以开始用了,相当简单!
注意:这里的数据源名称,不要带上奇奇怪怪的符号(比如中划线也不行),不然会解析不了!
测试读写分离
1)编写Mapper
建表和写实体类就不说了,贴个Mapper的代码吧,由于用的mybatis-plus,所以其实啥代码也不用写,就是空的:
@Mapper
@Repository
public interface ItemMapper extends BaseMapper<Item> {
}
2)测试读数据
@Test
void get() {
Item item = itemMapper.selectById(1);
System.out.println(JSON.toJSONString(item));
}
结果很明显,使用的是 slave 库:
3)测试写数据
@Test
void update() {
Item item = new Item();
item.setId(3);
item.setName("Springboot源码");
item.setUnitPrice(54);
item.setStock(31);
itemMapper.updateById(item);
}
结果同样很明显,使用的是 master 库:
当然,insert 以及 delete 操作,同样会使用 master 库。