Spring Boot 3整合ShardingSphere-Jdbc分库分表实战
目录
- 1. Maven 依赖
- 2. application.yml 配置
- 官网上是这么说的:
- 3. 配置要点
- 4. 数据库
- 4. 常见问题
- 5. 测试
- 1. 测试普通表插入
- 2. 测试普通表查询
- 3. 测试users表插入
- 4. 测试users表查询
网上找了很多资料,包括官网,使用springboot3加shardingsphere-jdbc都无法运行,查了GPT和网上搜索,摸索了一晚上,找到了方案。
1. Maven 依赖
<dependencies>
<!-- ShardingSphere JDBC 核心依赖 -->
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>shardingsphere-jdbc</artifactId>
<version>5.5.2</version>
</dependency>
<!-- Druid 数据源 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-3-starter</artifactId>
<version>1.2.27</version>
</dependency>
<!-- mysql 驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>8.4.0</version>
</dependency>
<!-- springboot -->
<dependency>
<groupId>org.springframework.boot</groupId>
javascript <artifactId>spring-boot-starter-web</artifactId>
<version>3.5.5</version>
</dependency>
</dependencies>
2. application.yml 配置
新版配置分为了两个文件,一个application.yml,另一个是sharding-datasource.yml
官网上是这么说的:
1. 首先 application.yml配置
server:
port: 9090
spring:
datasource:
driver-class-name: org.apache.shardingsphere.driver.ShardingSphereDriver # 指定了ShardingSphereDriver 为数据库驱动
url: jdbc:shardingsphere:classpath:sharding-datasource.yml # 指定classpath的sharding-datasource.yml文件
目录结构:

2. sharding-datasource.yml配置
mode:
type: Standalone # ShardingSphere 运行模式,Standalone 表示单机模式,不是集群模式
repository:
type: MEMORY # 元数据存储类型,MEMORY 表示元数据存储在内存中(也可用 JDBC 存储)
dataSources:
master: # master名字可以自定义 数据库主库(普通表 写库)
dataSourceClassName: com.alibaba.druid.pool.DruidDataSource # 使用 Druid 作为真实数据源
driverClassName: com.mysql.cj.jdbc.Driver # MySQL 驱动
url: jdbc:mysql://localhost:3306/tsuki-chat?useSSL=false&serverTimezone=Asia/Shanghai&allowpublicKeyRetrieval=true&nullCatalogMeansCurrent=true&rewriteBATchedStatements=true
username: root
password: 123456
slave: #slave名字可以自定义 数据库从库(普通表 从库)
dataSourceClassName: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3307/tsuki-chat?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true&rewriteBatchedStatements=true
username: root
password: 123456
users_master: # users表数据库主库(用于 users 表分库分表写入操作)
dataSourceClassName: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/tsuki-users?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true&rewriteBatchedStatements=true
username: root
password: 123456
users_slave: # users表数据库从库(用于 users 表分库分表读取操作)
dataSourceClassName: com.alibaba.druid.pool.DruidDataSource
driverClassName:编程客栈 com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3307/tsuki-users?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true&rewriteBatchedStphpatements=true
username: root
password: 123456
rules:
# 1️⃣ 全局表(除了 users 表)读写分离规则
- !REAdwRITE_SPLITTING
dataSourceGroups: # 必须用dataSourceGroups,用官网的dataSources会报错
readwrite_ds: # 逻辑数据源名(可自定义)
writeDataSourceName: master # 写库
readDataSourceNames: # 读库集合
- slave
transactionalReadQueryStrategy: PRIMARY # 事务读策略,PRIMARY 表示事务中读主库
loadBalancerName: random # 读库负载均衡策略
loadBalancers:
random: # 负载均衡算法配置
type: RANDOM # 随机选择读库
# 2️⃣ 针对users 表读写分离规则
- !READWRITE_SPLITTING
dataSourceGroups:
users_group: # users 表逻辑数据源名(可自定义)
writeDataSourceName: users_master # 写库
readDataSourceNames:
- users_slave # 读库
transactionalReadQueryStrategy: PRIMARY # 事务读策略,PRIMARY 表示事务中读主库
loadBalancerName: random android # 读库负载均衡策略
loadBalancers:
random:
type: RANDOM # 随机负载均衡
# 3️⃣ users 表分表规则
- !SHARDING
tables:
users:
actualDataNodes: users_group.users_${0..1} # 物理表名列表,users_0 和 users_1
tableStrategy:
standard:
shardingColumn: id # 分表字段
shardingAlgorithmName: user_algo # 使用分片算法 user_algo
shardingAlgorithms:
user_algo:
type: INLINE
props:
algorithm-expression: users_${id % 2} # 简单取模算法,将 id % 2 决定插入到 users_0 或 users_1
# 4️⃣ 其他非分片表(比如 Test、Message 等)走默认读写分离数据源
- !SINGLE
tables:
- "*.*" # 匹配所有其他表
defaultDataSource: readwrite_ds # 使用逻辑数据源 readwrite_ds(即 tsuki-chat 的读写分离)
props:
sql-show: true # 打印 SQL,便于调试
check-table: false # 不检查表是否存在,防止启动报错
default-data-source-name: readwrite_ds # 默认逻辑数据源
3. 配置要点
读写分离:
- 默认库 (
tsuki-chat) → 主从master/slave。 - users 专库 (
tsuki-users) → 主从users_master/users_slave。
- 默认库 (
分表:
users表按照id % 2分为users_0和users_1。普通表:通过
!SINGLE指定默认走readwrite_ds,避免TableNotFoundException。元数据模式:
repository: MEMORY→ 元数据存放在内存中,开发环境方便测试。
4. 数据库
数据库首先必须配置主从同步,最好从库禁用插入(这里教程很多,网上自己搭建)
首先有2个数据源,一共4个库tsuki-chat是我的普通表库,用于存放不用分库分表的库tsuki-users是我的分库分表库,用于users表分表
users分库分表(我有两张表)

4. 常见问题
- 报错
TableNotFoundException→ 没有配置!SINGLE,需要为非分片表指定默认数据源。 - 事务中读操作跑到从库 → 配置
transactionalReadQueryStrategy: PRIMARY,保证事务一致性。 - 测试数据回滚导致表为空 → 注意是否加了
@Transactional测试注解。
5. 测试
1. 测试普通表插入
@Test
public void test3() {
DbTest dbTest = new DbTest(1);
testMapper.insert(dbTest);
}
输出
2025-09-03T14:34:04.361+08:00 INFO 48308 --- [ main] ShardingSphere-SQL : Logic SQL: INSERT INTO db_test ( id ) VALUES ( ? )
2025-09-03T14:34:04.362+08:00 INFO 48308 --- [ main] ShardingSphere-SQL : Actual SQL: master ::: INSERT INTO db_test ( id ) VALUES ( ? ) ::: [114514]2025-09-03T14:34:04.436+08:00 INFO 48308 --- [ionShutdownHook] com.alibaba.druid.pool.DruidDataSource : {dataSource-1} closing ...2025-09-03T14:34:04.440+08:00 INFO 48308 --- [ionShutdownHook] com.alibaba.druid.pool.DruidDataSource : {dataSource-1} closed
我们可以看到输出了Actual SQL: master ::: INSERT INTO db_test ( id ) VALUES ( ? ) ::: [114514],说明写入走了master库

2. 测试普通表查询
@Test
public void test4() {
DbTest dbTest = testMapper.selectById(114514);
log.info(dbTest.toString());
}
输出
2025-09-03T14:39:28.865+08:00 INFO 37376 --- [ main] ShardingSphere-SQL : Logic SQL: SELECT id FROM db_test WHERE id=?
2025-09-03T14:39:28.865+08:00 INFO 37376 --- [ main] ShardingSphere-SQL : Actual SQL: slave ::: SELECT id FROM db_test WHERE id=? ::: [114514]2025-09-03T14:39:28.914+08:00 INFO 37376 --- [ main] c.t.c.server.TestChatServerApplication : DbTest(id=114514)
我们可以看到输出了Actual SQL: slave ::: SELECT id FROM db_test WHERE id=? ::: [114514],说明读取入走了slave库
3. 测试users表插入
@Test
public void test() {
List<User> users = generateUsers(10); // 生成10条users数据
List<BatchResult> insert = userMapper.insert(users);
log.info("插入成功");
}
输出
2025-09-03T15:00:10.253+08:00 INFO 47088 --- [ main] ShardingSphere-SQL : Actual SQL: users_master ::: INSERT INTO users_1 ( id, username, nickname, signature, email, password, avatar, mobile, login_date, logout_date, login_ip, join_type, sex, status, creator, create_time, updater, update_time, deleted ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ::: [1756882805969, userUbKYU, nickVpxsL, 签名AWTLp, userUbKYU@example.com, rjctPdFh, https://example.com/avatar/vYJQ.png, 15172505127, 2025-09-02T15:00:05.960025800, 2025-08-31T15:00:05.960025800, 192.168.215.80, 1, 1, 1, system, 2025-08-21T15:00:05.960025800, system, 2025-09-03T15:00:05.960025800, false]
2025-09-03T15:00:10.356+08:00 INFO 47088 --- [ main] c.t.c.server.TestChatServerApplication : 插入成功
我们可以看到输出了Actual SQL: users_master ::: INSERT INTO users_1 ,说明写入走了users_master库


4. 测试users表查询
@Test
public void test2() {
Page<User> userPage = new Page<User>(1, 8);
Page<User> selectedPage = userMapper.selectPage(userPage, null);
selectedPage.getRecords().forEach(user -> log.info(String.valueOf(user.getId())));
}
输出
2025-09-03T15:07:54.450+08:00 INFO 25284 --- [ main] ShardingSphere-SQL : Actual SQL: users_slave ::: SELECT id,username,nickname,signature,email,password,avatar,mobile,login_date,logout_date,login_ip,join_type,sex,status,creator,create_time,updater,update_time,deleted FROM users_1 LIMIT ? ::: [8]
2025-09-03T15:07:54.483+08:00 INFO 25284 --- [ main] c.t.c.server.TestChatServerApplication : 17568828059582025-09-03T15:07:54.484+08:00 INFO 25284 --- [ main] c.t.c.server.TestChatServerApplication : 17568828059602025-09-03T15:07:54.484+08:00 INFO 25284 --- [ main] c.t.c.server.TestChatServerApplication : 17568828059622025-09-03T15:07:54.484+08:00 INFO 25284 --- [ main] c.t.c.server.TestChatServerApplication : 17568828059642025-09-03T15:07:54.484+08:00 INFO 25284 --- [ main] c.t.c.server.TestChatServerApplicatiojsn : 17568828059662025-09-03T15:07:54.484+08:00 INFO 25284 --- [ main] c.t.c.server.TestChatServerApplication : 17568828059612025-09-03T15:07:54.484+08:00 INFO 25284 --- [ main] c.t.c.server.TestChatServerApplication : 17568828059632025-09-03T15:07:54.484+08:00 INFO 25284 --- [ main] c.t.c.server.TestChatServerApplication : 1756882805965
我们可以看到输出了Actual SQL: users_slave ::: SELECT ,说明读取走了users_slave库
✅ 这样配置后:
users表支持 分库 + 分表 + 读写分离test、orders等普通表支持 全局读写分离- SQL 路由清晰可控,适合生产环境逐步扩展。
到此这篇关于Spring Boot 3整合ShardingSphere-Jdbc分库分表实战的文章就介绍到这了,更多相关Spring Boot 3 ShardingSphere-Jdbc分库分表内容请搜索编程客栈(www.devze.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程客栈(www.devze.com)!
加载中,请稍侯......
精彩评论