mybatis-flex/docs/zh/core/read-write-splitting.md
2023-09-24 09:24:50 +08:00

105 lines
3.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 读写分离
MyBatis-Flex 的读写分离功能是基于 【[多数据源](./multi-datasource.md)】 功能来实现的。
读写分离的功能,要求当前环境必须是多个数据库(也可理解为多个数据源),其原理是:
让主数据库master处理事务性操作比如增、删、改INSERT、DELETE、UPDATE而从数据库slave处理查询SELECT操作。
## 实现原理
在 MyBatis 框架中,我们知道: 所有关于数据库的的操作都是通过 Mapper 来进行的Mapper 里的一个方法,往往是和一个执行 SQL 一一对应。
因此,在 MyBatis-Flex 中,提供了一种基于 Mapper 方法的读写分离策略。
## 数据源分片策略
在 MyBatis-Flex 框架中,我们需要通过实现 `DataSourceShardingStrategy` 接口来自定义自己的数据源读写分离策略(分片策略)例如:
```java
public class MyStrategy implements DataSourceShardingStrategy {
public String doSharding(String currentDataSourceKey
, Object mapper, Method mapperMethod, Object[] methodArgs){
//返回新的数据源 key
return "newDataSourceKey";
}
}
```
doSharding 的参数分别为:
- currentDataSourceKey当前使用的数据源 key
- mapper当前的 mapper 对象
- mapperMethod: 当前的 mapper 方法
- methodArgs当前的 mapper 方法的参数内容
自定义好 数据源分片策略后,在项目启动时,需要通过 `DataSourceManager` 配置自己的自定义分片策略:
```java
DataSourceManager.setDataSourceShardingStrategy(new MyStrategy());
```
## 示例代码
假设数据源配置如下:
```yaml
mybatis-flex:
datasource:
master:
type: druid
url: jdbc:mysql://127.0.0.1:3306/master-db
username: root
password: 123456
slave1:
type: com.your.datasource.type2
url: jdbc:mysql://127.0.0.1:3306/slave1
username: root
password: 123456
slave2:
type: com.your.datasource.type2
url: jdbc:mysql://127.0.0.1:3306/slave2
username: root
password: 123456
other:
type: com.your.datasource.type2
url: jdbc:mysql://127.0.0.1:3306/other
username: root
password: 123456
```
以上配置中,一共有 4 个数据源,分别为 `master``slave1``slave2``other`
我们的需求是:在 增删改 时,走 master 数据源,而在查询时,随机自动使用 `slave1``slave2` 数据源进行负载均衡。
那么,我们的分片策略代码如下:
```java
public class MyStrategy implements DataSourceShardingStrategy {
public String doSharding(String currentDataSourceKey
, Object mapper, Method mapperMethod, Object[] methodArgs){
// 不管 other 数据源的情况
if ("other".equals(currentDataSourceKey)){
return currentDataSourceKey;
}
// 如果 mapper 的方法属于 增删改,使用 master 数据源
if (StringUtil.startWithAny(mapperMethod.getName(),
"insert", "delete", "update")){
return "master";
}
//其他场景,使用 slave1 或者 slave2 进行负载均衡
return "slave*";
}
}
```
## 注意事项
> MyBatis-Flex 的读写分离组件,只进行数据查询和数据操作时的读写分离,并不涉及主从数据库之间的数据同步,主从数据库同步需要用户自己在数据库服务器,通过第三方组件去实现。