SpringBoot3 + ShardingSphere-JDBC5.5.2 分库分表

摘要

maven依赖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!-- 本项目 基于 mysql -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<!-- mybatis plus,本项目用到,非必须 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
<version>3.5.12</version>
</dependency>
<!-- ShardingSphere JDBC 主依赖(5.5.2 建议) -->
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>shardingsphere-jdbc</artifactId>
<version>5.5.2</version>
</dependency>

application.yml

1
2
3
4
5
spring:
datasource:
driver-class-name: org.apache.shardingsphere.driver.ShardingSphereDriver
# 指向类路径下的 sharding.yaml(也可 absolute path / file: / http: 等,见官方说明)
url: jdbc:shardingsphere:classpath:sharding.yaml
  • 也可以不在 application.yml 中配置,而是通过 @Configuration 创建 @Bean,这样就可以配置多数据源了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Configuration
public class DataSourceConfig {

@Bean(name = "shardingDataSource")
public DataSource shardingDataSource() throws SQLException, IOException {
// ShardingSphere 提供的工厂方法,根据配置构建 DataSource
try (InputStream inputStream = getClass().getClassLoader().getResourceAsStream("sharding.yaml")) {
if (inputStream == null) {
throw new IllegalStateException("Cannot find sharding.yaml in classpath");
}
byte[] yamlBytes = inputStream.readAllBytes();
return YamlShardingSphereDataSourceFactory.createDataSource(yamlBytes);
}
}
}

sharding.yaml

  • 完整配置,下文会介绍部分配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
# 数据源配置: https://shardingsphere.apache.org/document/current/cn/user-manual/shardingsphere-jdbc/yaml-config/data-source/
dataSources:
ds_0: # 逻辑数据源名称
dataSourceClassName: com.zaxxer.hikari.HikariDataSource
driverClassName: com.mysql.cj.jdbc.Driver
jdbcUrl: jdbc:mysql://127.0.0.1:3306/shardingdb0?useSSL=false&serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8
username: root
password: newpwd

ds_1:
dataSourceClassName: com.zaxxer.hikari.HikariDataSource
driverClassName: com.mysql.cj.jdbc.Driver
jdbcUrl: jdbc:mysql://127.0.0.1:3306/shardingdb1?useSSL=false&serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8
username: root
password: newpwd

# 分片规则配置: https://shardingsphere.apache.org/document/current/cn/user-manual/shardingsphere-jdbc/yaml-config/rules/sharding/
rules:
- !SHARDING # 分片规则配置
# 绑定表:同分片键 join 时走同路由,减少广播,多个逗号分隔,要求分片规则一致
bindingTables:
- t_order,t_order_item

tables: # 手工分片规则配置
course: # 逻辑表名称
actualDataNodes: ds_${0..1}.course_${1..2} # 实际数据节点
databaseStrategy: # 分库策略
standard: # 用于单分片键的标准分片场景
shardingColumn: user_id # 分片列名称
shardingAlgorithmName: course_db_inline # 分片算法名称
tableStrategy: # 分表策略
standard:
shardingColumn: cid
shardingAlgorithmName: course_inline
keyGenerateStrategy: # 分布式序列策略
column: cid # 自增列名称
keyGeneratorName: snowflake # 分布式序列算法名称
t_order_complex: # 逻辑表名称
actualDataNodes: ds_${0..1}.t_order_complex_${0..1} # 实际数据节点
databaseStrategy: # 分库策略
standard: # 用于单分片键的标准分片场景
shardingColumn: user_id # 分片列名称
shardingAlgorithmName: t_order_db_inline # 分片算法名称
tableStrategy: # 分表策略
complex: # 用于多分片键的复杂分片场景
shardingColumns: user_id,order_id
shardingAlgorithmName: t_order-complex-algorithm
keyGenerateStrategy: # 分布式序列策略
column: order_id # 自增列名称
keyGeneratorName: snowflake # 分布式序列算法名称
t_order_item_complex: # 逻辑表名称
actualDataNodes: ds_${0..1}.t_order_item_complex_${0..1} # 实际数据节点
databaseStrategy: # 分库策略
standard: # 用于单分片键的标准分片场景
shardingColumn: user_id # 分片列名称
shardingAlgorithmName: t_order_db_inline # 分片算法名称
tableStrategy: # 分表策略
complex: # 用于多分片键的复杂分片场景
shardingColumns: user_id,order_id # 分片列名称,多个逗号分隔
# shardingAlgorithmName: t_order_item-class-based-algorithm # 基于自定义类的分片算法
shardingAlgorithmName: t_order_item-class-based-algorithm_spi # 基于 SPI 的分片算法,效果同上,建议生产环境使用 SPI
keyGenerateStrategy: # 分布式序列策略
column: item_id # 自增列名称
keyGeneratorName: snowflake # 分布式序列算法名称

t_user:
actualDataNodes: ds_${0..1}.t_user_${0..1} # 实际数据节点
databaseStrategy: # 分库策略
standard: # 用于单分片键的标准分片场景
shardingColumn: id # 分片列名称
shardingAlgorithmName: t_user_db_inline # 分片算法名称
tableStrategy: # 分表策略
standard:
shardingColumn: id # 分片列名称
shardingAlgorithmName: t_user_inline # 分片算法名称
keyGenerateStrategy: # 分布式序列策略
column: id # 自增列名称,字符串类型
# keyGeneratorName: uuid # 分布式序列算法名称
keyGeneratorName: custom_snowflake_string # 分布式序列算法名称


# t_address: # 普通表(不分库分表,绑定到 ds_0),没有默认的数据源配置,所以每个都要显示声明
# actualDataNodes: ds_0.t_address # 实际数据节点

autoTables: # 自动分片规则配置
t_order: # 逻辑表名称
actualDataSources: ds_${0..1} # 数据源名称
shardingStrategy: # 切分策略
standard: # 用于单分片键的标准分片场景
shardingColumn: user_id # 分片列名称
shardingAlgorithmName: mod_2 # 自动分片算法名称
keyGenerateStrategy: # 分布式序列策略
column: order_id # 自增列名称
keyGeneratorName: snowflake # 分布式序列算法名称
t_order_item: # 逻辑表名称
actualDataSources: ds_${0..1} # 数据源名称
shardingStrategy: # 切分策略
standard: # 用于单分片键的标准分片场景
shardingColumn: user_id # 分片列名称
shardingAlgorithmName: mod_2 # 自动分片算法名称
keyGenerateStrategy: # 分布式序列策略
column: item_id # 自增列名称
keyGeneratorName: snowflake # 分布式序列算法名称

shardingAlgorithms: # 分片算法 https://shardingsphere.apache.org/document/current/cn/dev-manual/sharding/
course_inline: # 定义名称,在上面引用
type: INLINE # 基于行表达式的分片算法,这里使用 MOD 会报错
props: # 属性
algorithm-expression: course_${cid % 2 + 1} # 表达式,这是因为表名称为 course_1, course_2
allow-range-query-with-inline-sharding: true # 允许范围查询
course_db_inline:
type: INLINE
props:
algorithm-expression: ds_${user_id % 2} # 表示 ds_0, ds_1
mod_2:
type: MOD # 基于 MOD 的分片算法
props:
sharding-count: 2 # 分片数量,即 对 2 进行取余
t_order_db_inline:
type: INLINE
props:
algorithm-expression: ds_${user_id % 2}
t_order-complex-algorithm:
type: COMPLEX_INLINE # 基于行表达式的复合分片算法
props:
algorithm-expression: t_order_complex_${(user_id + order_id + 1) % 2}
t_order_item-class-based-algorithm:
type: CLASS_BASED # 基于自定义类的分片算法
props:
strategy: COMPLEX # 指定策略 STANDARD|COMPLEX|HINT ,告诉 ShardingSphere 分片算法类实现了什么策略
algorithmClassName: com.hanqf.demo.support.algorithm.OrderItemComplexAlgorithm # 指定算法类
t_order_item-class-based-algorithm_spi: # SPI
type: T_ORDER_ITEM_COMPLEX # 基于自定义类的分片算法
t_user_db_inline:
type: INLINE
props:
algorithm-expression: ds_${Math.abs(id.hashCode()%2)}
t_user_inline:
type: INLINE
props:
algorithm-expression: t_user_${Math.abs(id.hashCode()%4).intdiv(2)}

keyGenerators: # 分布式主键生成器: https://shardingsphere.apache.org/document/current/cn/user-manual/common-config/builtin-algorithm/keygen/
snowflake: # 定义名称,在上面引用
type: SNOWFLAKE # 使用雪花算法,Long
uuid: # 定义名称
type: UUID # 字符串主键,String
custom_snowflake_string:
type: CUSTOM_SNOWFLAKE_STRING # 自定义雪花算法,String
props:
workerId: 2
datacenterId: 2

- !BROADCAST # 广播表配置,即所有的库中都包含指定的表,写入数据时同时写入多个库,查询时随机读一个
tables:
- dict # 广播表名称,⼴播表不能配置分表逻辑,只往多个库的同⼀个表中插⼊数据。

- !ENCRYPT # 数据加密配置
tables:
t_user: # 加密表名称
columns:
password: # 加密列名称
cipher:
name: password # 密文列名称
encryptorName: aes_encryptor # 密文列加密算法名称
# 加密算法配置: https://shardingsphere.apache.org/document/current/cn/user-manual/common-config/builtin-algorithm/encrypt/
encryptors:
aes_encryptor: # 加解密算法名称
type: AES # 加解密算法类型
props: # 加解密算法属性配置
aes-key-value: 123456abc # AES 使用的 KEY
digest-algorithm-name: SHA-1 # AES KEY 的摘要算法
md5_encryptor:
type: MD5
props:
salt: 123456 # 盐值(可选)

- !MASK # 数据脱敏配置
tables:
t_user: # 脱敏表名称
columns: # 脱敏列配置
password: # 脱敏列名称
maskAlgorithm: md5_mask # 脱敏算法名称
email:
maskAlgorithm: mask_before_special_chars_mask
telephone:
maskAlgorithm: keep_first_n_last_m_mask
name:
maskAlgorithm: my_mask

maskAlgorithms: # 脱敏算法配置
md5_mask: # 自定义脱敏算法名称
type: MD5 # 脱敏算法类型,md5加密后展示
mask_before_special_chars_mask:
type: MASK_BEFORE_SPECIAL_CHARS # 在特殊字符(比如邮箱里的 @)前面做脱敏,示例:myemail@example.com → *******@example.com
props:
special-chars: '@' # 遇到 @ 之前的部分做脱敏
replace-char: '*' # 脱敏字符用 * 代替
keep_first_n_last_m_mask:
type: KEEP_FIRST_N_LAST_M # 保留前 n 位和后 m 位,其余用替换字符填充,示例:13812345678 → 138****5678
props:
first-n: 3 # 保留前 3 位
last-m: 4 # 保留后 4 位
replace-char: '*' # 脱敏字符用 * 代替
my_mask:
type: MY_CUSTOM_MASK # 自定义脱敏算法名称
props:
replace-char: "#"


- !SINGLE # 单表规则配置,单表规则优先级高于分库分表规则
tables:
# MySQL 风格
- ds_0.t_address # 加载指定单表
# - ds_1.* # 加载指定数据源中的全部单表
# - "*.*" # 加载全部单表

# 属性配置:https://shardingsphere.apache.org/document/current/cn/user-manual/common-config/props/
props:
sql-show: true # 控制台打印改写后的 SQL,便于排错,默认为 false
check-table-metadata-enabled: false # 在程序启动和更新时,是否检查分片元数据的结构一致性,默认为 false

数据源配置

  • hikari + mysql

1
2
3
4
5
6
7
8
9
10
11
12
13
14
dataSources:
ds_0: # 逻辑数据源名称
dataSourceClassName: com.zaxxer.hikari.HikariDataSource
driverClassName: com.mysql.cj.jdbc.Driver
jdbcUrl: jdbc:mysql://127.0.0.1:3306/shardingdb0?useSSL=false&serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8
username: root
password: newpwd

ds_1:
dataSourceClassName: com.zaxxer.hikari.HikariDataSource
driverClassName: com.mysql.cj.jdbc.Driver
jdbcUrl: jdbc:mysql://127.0.0.1:3306/shardingdb1?useSSL=false&serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8
username: root
password: newpwd
  • druid + mysql

1
2
3
4
5
6
7
8
9
10
11
12
13
14
dataSources:
ds_1:
dataSourceClassName: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/shardingdb1?useSSL=false&serverTimezone=UTC
username: root
password: newpwd
# Druid 特有配置
initialSize: 5
minIdle: 5
maxActive: 20
maxWait: 60000
testWhileIdle: true
validationQuery: SELECT 1 FROM DUAL
  • druid + mysql + p6spy

1
2
3
4
5
6
7
8
9
10
11
12
13
14
dataSources:
ds_0: # 逻辑数据源名称
dataSourceClassName: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.p6spy.engine.spy.P6SpyDriver
url: jdbc:p6spy:mysql://127.0.0.1:3306/shardingdb0?useSSL=false&serverTimezone=UTC
username: root
password: newpwd
# Druid 特有配置
initialSize: 5
minIdle: 5
maxActive: 20
maxWait: 60000
testWhileIdle: true
validationQuery: SELECT 1 FROM DUAL

分库分表配置

单分片键,Long 类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
rules:
- !SHARDING # 分片规则配置
tables: # 手工分片规则配置
course: # 逻辑表名称
actualDataNodes: ds_${0..1}.course_${1..2} # 实际数据节点,建表时写成了 1和2,懒得改了,所以下面分表规则中对2取余后要+1
databaseStrategy: # 分库策略
standard: # 用于单分片键的标准分片场景
shardingColumn: user_id # 分片列名称
shardingAlgorithmName: course_db_inline # 分片算法名称
tableStrategy: # 分表策略
standard:
shardingColumn: cid
shardingAlgorithmName: course_inline
keyGenerateStrategy: # 分布式序列策略
column: cid # 自增列名称
keyGeneratorName: snowflake # 分布式序列算法名称

shardingAlgorithms: # 分片算法
course_inline: # 定义名称,在上面引用
type: INLINE # 基于行表达式的分片算法,这里使用 MOD 会报错
props: # 属性
algorithm-expression: course_${cid % 2 + 1} # 表达式,这是因为表名称为 course_1, course_2
allow-range-query-with-inline-sharding: true # 允许范围查询
course_db_inline:
type: INLINE
props:
algorithm-expression: ds_${user_id % 2} # 表示 ds_0, ds_1

keyGenerators: # 分布式主键生成器
snowflake: # 定义名称,在上面引用
type: SNOWFLAKE # 使用雪花算法,Long
  • 这里分库与分表采用了不同的字段,分库使用 user_id,分表使用 cid

  • allow-range-query-with-inline-sharding: true ,这里设置为允许范围查询,默认值是 false,不允许 between 查询

单分片键,String 类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
rules:
- !SHARDING # 分片规则配置
tables: # 手工分片规则配置
t_user:
actualDataNodes: ds_${0..1}.t_user_${0..1} # 实际数据节点
databaseStrategy: # 分库策略
standard: # 用于单分片键的标准分片场景
shardingColumn: id # 分片列名称
shardingAlgorithmName: t_user_db_inline # 分片算法名称
tableStrategy: # 分表策略
standard:
shardingColumn: id # 分片列名称
shardingAlgorithmName: t_user_inline # 分片算法名称
keyGenerateStrategy: # 分布式序列策略
column: id # 自增列名称,字符串类型
# keyGeneratorName: uuid # 分布式序列算法名称
keyGeneratorName: custom_snowflake_string # 分布式序列算法名称

shardingAlgorithms: # 分片算法
t_user_db_inline:
type: INLINE
props:
algorithm-expression: ds_${Math.abs(id.hashCode()%2)} # 分库,ds_0, ds_1,id 为字符串,所以要转换为数字再进行运算
t_user_inline:
type: INLINE
props:
algorithm-expression: t_user_${Math.abs(id.hashCode()%4).intdiv(2)} # 分表,t_user_0, t_user_1

keyGenerators: # 分布式序列算法
uuid: # 定义名称
type: UUID # 字符串主键,String
custom_snowflake_string:
type: CUSTOM_SNOWFLAKE_STRING # 自定义雪花算法,String,spi
props:
workerId: 2
datacenterId: 2
  • 这里分库与分表采用了相同的字段,即主键id,因其为字符串类型,所以需要使用 hashCode() 获取数字,再进行运算

  • 主键获取规则使用的自定义的雪花算法,spi,详见src/main/resources/META-INF/services/org.apache.shardingsphere.infra.algorithm.keygen.core.KeyGenerateAlgorithm,这里注意,从 5.5.3 开始会更换为 org.apache.shardingsphere.infra.algorithm.keygen.spi.KeyGenerateAlgorithm

多分片键,Long 类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
rules:
- !SHARDING # 分片规则配置
tables: # 手工分片规则配置
t_order_complex: # 逻辑表名称
actualDataNodes: ds_${0..1}.t_order_complex_${0..1} # 实际数据节点
databaseStrategy: # 分库策略
standard: # 用于单分片键的标准分片场景
shardingColumn: user_id # 分片列名称
shardingAlgorithmName: t_order_db_inline # 分片算法名称
tableStrategy: # 分表策略
complex: # 用于多分片键的复杂分片场景
shardingColumns: user_id,order_id
shardingAlgorithmName: t_order-complex-algorithm
keyGenerateStrategy: # 分布式序列策略
column: order_id # 自增列名称
keyGeneratorName: snowflake # 分布式序列算法名称
t_order_item_complex: # 逻辑表名称
actualDataNodes: ds_${0..1}.t_order_item_complex_${0..1} # 实际数据节点
databaseStrategy: # 分库策略
standard: # 用于单分片键的标准分片场景
shardingColumn: user_id # 分片列名称
shardingAlgorithmName: t_order_db_inline # 分片算法名称
tableStrategy: # 分表策略
complex: # 用于多分片键的复杂分片场景
shardingColumns: user_id,order_id # 分片列名称,多个逗号分隔
# shardingAlgorithmName: t_order_item-class-based-algorithm # 基于自定义类的分片算法
shardingAlgorithmName: t_order_item-class-based-algorithm_spi # 基于 SPI 的分片算法,效果同上,建议生产环境使用 SPI
keyGenerateStrategy: # 分布式序列策略
column: item_id # 自增列名称
keyGeneratorName: snowflake # 分布式序列算法名称

shardingAlgorithms: # 分片算法
t_order_db_inline:
type: INLINE
props:
algorithm-expression: ds_${user_id % 2}
t_order-complex-algorithm:
type: COMPLEX_INLINE # 基于行表达式的复合分片算法
props:
algorithm-expression: t_order_complex_${(user_id + order_id + 1) % 2}
t_order_item-class-based-algorithm:
type: CLASS_BASED # 基于自定义类的分片算法
props:
strategy: COMPLEX # 指定策略 STANDARD|COMPLEX|HINT ,告诉 ShardingSphere 分片算法类实现了什么策略
algorithmClassName: com.hanqf.demo.support.algorithm.OrderItemComplexAlgorithm # 指定算法类
t_order_item-class-based-algorithm_spi: # SPI
type: T_ORDER_ITEM_COMPLEX # 基于自定义类的分片算法

keyGenerators: # 分布式主键生成器
snowflake: # 定义名称,在上面引用
type: SNOWFLAKE # 使用雪花算法,Long
  • 多个分片键,t_order_complex表使用了内置的COMPLEX_INLINE算法,而t_order_item_complex表使用了自定义的的分片算法,spi,详见src/main/resources/META-INF/services/org.apache.shardingsphere.sharding.spi.ShardingAlgorithm

自动分片规则

  • 上面介绍的都是手工配置分片规则,用于配置较为复杂的分片规则,如果分片规则比价简单,可以使用自动分片规则

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
rules:
- !SHARDING # 分片规则配置
# 绑定表:同分片键 join 时走同路由,多个逗号分隔,要求分片规则一致
bindingTables:
- t_order,t_order_item
autoTables: # 自动分片规则配置
t_order: # 逻辑表名称
actualDataSources: ds_${0..1} # 数据源名称
shardingStrategy: # 切分策略
standard: # 用于单分片键的标准分片场景
shardingColumn: user_id # 分片列名称
shardingAlgorithmName: mod_2 # 自动分片算法名称
keyGenerateStrategy: # 分布式序列策略
column: order_id # 自增列名称
keyGeneratorName: snowflake # 分布式序列算法名称
t_order_item: # 逻辑表名称
actualDataSources: ds_${0..1} # 数据源名称
shardingStrategy: # 切分策略
standard: # 用于单分片键的标准分片场景
shardingColumn: user_id # 分片列名称
shardingAlgorithmName: mod_2 # 自动分片算法名称
keyGenerateStrategy: # 分布式序列策略
column: item_id # 自增列名称
keyGeneratorName: snowflake # 分布式序列算法名称

shardingAlgorithms: # 分片算法
mod_2:
type: MOD # 基于 MOD 的分片算法
props:
sharding-count: 2 # 分片数量,即 对 2 进行取余

keyGenerators: # 分布式主键生成器
snowflake: # 定义名称,在上面引用
type: SNOWFLAKE # 使用雪花算法,Long
  • 自动分片规则需要声明数据库,但不需要声明表分配规则,其根据分片算法自动确定具体的数据表。

  • 同时这里还配置了bindingTables,用来指定其分片路由一致。

广播表配置

  • 广播表,即所有数据源都包含的表,比如字典表

1
2
3
4
rules:
- !BROADCAST # 广播表配置,即所有的库中都包含指定的表,写入数据时同时写入多个库,查询时随机读一个
tables:
- dict # 广播表名称,⼴播表不能配置分表逻辑,只往多个库的同⼀个表中插⼊数据。

数据加密规则

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
rules:
- !ENCRYPT # 数据加密配置
tables:
t_user: # 加密表名称
columns:
password: # 加密列名称
cipher:
name: password # 密文列名称
encryptorName: aes_encryptor # 密文列加密算法名称
# 加密算法配置: https://shardingsphere.apache.org/document/current/cn/user-manual/common-config/builtin-algorithm/encrypt/
encryptors:
aes_encryptor: # 加解密算法名称
type: AES # 加解密算法类型
props: # 加解密算法属性配置
aes-key-value: 123456abc # AES 使用的 KEY
digest-algorithm-name: SHA-1 # AES KEY 的摘要算法
md5_encryptor:
type: MD5
props:
salt: 123456 # 盐值(可选)
  • 配置加密字段规则后,新增数据时,会自动对加密字段加密后存储,查询时也会加密后进行比较查询。

数据脱敏规则

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
rules:
- !MASK # 数据脱敏配置
tables:
t_user: # 脱敏表名称
columns: # 脱敏列配置
password: # 脱敏列名称
maskAlgorithm: md5_mask # 脱敏算法名称
email:
maskAlgorithm: mask_before_special_chars_mask
telephone:
maskAlgorithm: keep_first_n_last_m_mask
name:
maskAlgorithm: my_mask

maskAlgorithms: # 脱敏算法配置
md5_mask: # 自定义脱敏算法名称
type: MD5 # 脱敏算法类型,md5加密后展示
mask_before_special_chars_mask:
type: MASK_BEFORE_SPECIAL_CHARS # 在特殊字符(比如邮箱里的 @)前面做脱敏,示例:myemail@example.com → *******@example.com
props:
special-chars: '@' # 遇到 @ 之前的部分做脱敏
replace-char: '*' # 脱敏字符用 * 代替
keep_first_n_last_m_mask:
type: KEEP_FIRST_N_LAST_M # 保留前 n 位和后 m 位,其余用替换字符填充,示例:13812345678 → 138****5678
props:
first-n: 3 # 保留前 3 位
last-m: 4 # 保留后 4 位
replace-char: '*' # 脱敏字符用 * 代替
my_mask:
type: MY_CUSTOM_MASK # 自定义脱敏算法名称
props:
replace-char: "#"
  • 被脱敏的字段在查询时会进行脱敏展示。

  • 这里还自定义了脱敏算法,spi,详见src/main/resources/META-INF/services/org.apache.shardingsphere.mask.spi.MaskAlgorithm

单表规则

  • 即不需要进行分库分表的表

1
2
3
4
5
rules:
- !SINGLE # 单表规则配置,单表规则优先级高于分库分表规则
tables:
# MySQL 风格
- ds_0.t_address # 加载指定单表

其它属性配置

1
2
3
4
# 属性配置:https://shardingsphere.apache.org/document/current/cn/user-manual/common-config/props/
props:
sql-show: true # 控制台打印改写后的 SQL,便于排错,默认为 false
check-table-metadata-enabled: false # 在程序启动和更新时,是否检查分片元数据的结构一致性,默认为 false

后记

  • springboot3 集成 shardingsphere5.5.2 与 springboot2 不同,不再提供 springboot-starter-shardingsphere,相关配置也采用了独立的配置文件。

  • 代码中包含两个库中使用到的数据库脚本,shardingsphere-demo/shardingsphere-demo-01/sql

  • 具体使用效果可以通过项目中提供的单元测试类进行验证。