一、说明
版本选择很重要,切记,我使用的 springboot是
java
<spring-boot.version>3.0.5</spring-boot.version>
shardingsphere版本是
java
<version>5.4.0</version>
mybatisPlus版本
java
<mybatis-plus.version>3.5.11</mybatis-plus.version>
pom.xml一定要加入下面这两个依赖,否则运行会报错,官方有说明
java
<!--兼容jdk17和spring boot3-->
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>1.33</version>
</dependency>
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>2.3.8</version>
</dependency>
其他的版本有问题,目前还没有时间去研究,如果只是学校可以直接参考这个版本,不会错
完成的需求:保存数据到两个库shs_db0,shs_db1中,两个数据库的表结构往前一致,如下图,
保存数据根据id保存,id 生成雪花算法;贴上代码,最后再看结果就ok,可以直接复制代码去使用
最重要的是sharding.yaml这个文件,下面代码注意看

二、创建表
shs_user表
sql
CREATE TABLE `shs_user_1` (
`id` bigint NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL COMMENT '名字',
`sex` int DEFAULT NULL COMMENT '性别:1男 2女',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2080220072798011395 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='sharedingshpere用户表';
shs_order表
sql
CREATE TABLE `shs_order_1` (
`order_id` bigint NOT NULL AUTO_INCREMENT,
`shop_name` varchar(255) DEFAULT NULL COMMENT '商品名称',
`amount` int DEFAULT NULL COMMENT '商家价格',
`user_id` bigint DEFAULT NULL COMMENT '用户id',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
PRIMARY KEY (`order_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=2080220072798011396 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='sharedingshpere订单表';
项目结构

三、加入pom依赖
直接复制过去使用就行了
java
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.hx</groupId>
<artifactId>shareding</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring-boot.version>3.0.5</spring-boot.version>
<!--<spring-boot.version>3.5.11</spring-boot.version>-->
<knife4j.version>4.3.0</knife4j.version>
<mybatis-plus.version>3.5.11</mybatis-plus.version>
<druid.version>1.2.28</druid.version>
</properties>
<dependencies>
<!-- web应用程序核心依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 编写和运行测试用例 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>shardingsphere-jdbc-core</artifactId>
<version>5.4.0</version>
</dependency>
<!--兼容jdk17和spring boot3-->
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>1.33</version>
</dependency>
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>2.3.8</version>
</dependency>
<!-- MySQL8驱动 runtime作用域 -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>8.0.33</version>
</dependency>
<!-- 阿里数据库连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-3-starter</artifactId>
<version>${druid.version}</version>
</dependency>
<!-- MyBatis-Plus SpringBoot3 启动器 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.30</version>
<optional>true</optional>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<!--引入SpringBoot依赖管理清单-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<repositories>
<repository>
<id>central</id>
<url>https://repo1.maven.org/maven2/</url>
</repository>
</repositories>
</project>
四、配置yml
application.yml如下
java
# 开发环境配置
server:
# 服务器的HTTP端口,默认为8080
port: 8080
servlet:
# 应用的访问路径
context-path: /
tomcat:
# tomcat的URI编码
uri-encoding: UTF-8
# 连接数满后的排队数,默认为100
accept-count: 1000
threads:
# tomcat最大线程数,默认为200
max: 800
# Tomcat启动初始化的线程数,默认值10
min-spare: 100
# 日志配置
logging:
level:
com.ruoyi: debug
org.springframework: warn
# Spring配置
spring:
# 文件上传
servlet:
multipart:
# 单个文件大小
max-file-size: 10MB
# 设置总上传的文件大小
max-request-size: 20MB
jackson:
time-zone: GMT+8
date-format: yyyy-MM-dd HH:mm:ss
# 服务模块
devtools:
restart:
# 热部署开关
enabled: true
datasource:
driver-class-name: org.apache.shardingsphere.driver.ShardingSphereDriver
url: jdbc:shardingsphere:classpath:sharding.yaml
# Mybatis-Plus配置
mybatis-plus:
mapper-locations: classpath:mapper/**/*.xml
type-aliases-package: com.hx.shared.entity
configuration:
map-underscore-to-camel-case: true
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
global-config:
db-config:
id-type: auto
sharding.yaml如下
java
# 多数据源配置(不变,沿用原有m0、m1)
dataSources:
# 第一个数据源:库 shs_db0,别名 m0
m0:
# MySQL连接地址:本地3306端口,数据库shs_db0,附加连接参数
# useUnicode=true:开启unicode编码;characterEncoding=utf8:字符集utf8
# zeroDateTimeBehavior=convertToNull:数据库0日期转为null避免报错
# useSSL=true:启用SSL安全连接;serverTimezone=GMT+8:东八区时区
url: jdbc:mysql://localhost:3306/shs_db0?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
# 数据库登录账号
username: root
# 数据库登录密码
password: 123456
# MySQL8.x驱动类全限定名(cj包新版驱动)
driverClassName: com.mysql.cj.jdbc.Driver
# 指定连接池为阿里Druid数据源
dataSourceClassName: com.alibaba.druid.pool.DruidDataSource
# 第二个数据源:库 shs_db1,别名 m1
m1:
# MySQL连接地址:本地3306端口,数据库shs_db1,参数同m0
url: jdbc:mysql://localhost:3306/shs_db1?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
# 数据库登录账号
username: root
# 数据库登录密码
password: 123456
# MySQL8.x驱动类
driverClassName: com.mysql.cj.jdbc.Driver
# Druid连接池实现类
dataSourceClassName: com.alibaba.druid.pool.DruidDataSource
# 分片规则总配置入口
rules:
# 标识当前规则类型为分库分表SHARDING规则
- !SHARDING
# 分片表定义,配置需要分片的逻辑表
tables:
# 原有用户分片表配置不变
shs_user:
# 真实数据节点表达式:数据源m0/m1 + 每张库内分表shs_user_1、shs_user_2
# 完整节点:m0.shs_user_1,m0.shs_user_2,m1.shs_user_1,m1.shs_user_2
actualDataNodes: m$->{0..1}.shs_user_$->{1..2}
# 分库策略配置
databaseStrategy:
# 标准分片策略(单分片字段场景用standard)
standard:
# 分库依据字段:id
shardingColumn: id
# 绑定分库算法名称,下方shardingAlgorithms中定义
shardingAlgorithmName: shs_user_db_alg
# 分表策略配置
tableStrategy:
# 标准分片策略
standard:
# 分表依据字段:id
shardingColumn: id
# 绑定分表算法名称,下方shardingAlgorithms中定义
shardingAlgorithmName: shs_user_tb_alg
# 主键生成策略,逻辑表id自动生成
keyGenerateStrategy:
# 自增主键字段
column: id
# 绑定主键生成器名称,下方keyGenerators定义
keyGeneratorName: my_snowflake
# 逻辑表名:shs_order(业务代码只操作这个逻辑表)
shs_order:
# 真实数据节点:m0/m1库下都存在 shs_order_1、shs_order_2
actualDataNodes: m$->{0..1}.shs_order_$->{1..2}
# 分库策略:按userId分片,订单跟随用户库,减少跨库join
databaseStrategy:
standard:
# 分库字段userId,和用户分片键对齐
shardingColumn: user_id
# 绑定订单分库算法
shardingAlgorithmName: shs_order_db_alg
# 分表策略:同样按userId分表
tableStrategy:
standard:
shardingColumn: user_id
shardingAlgorithmName: shs_order_tb_alg
# 主键生成:id使用雪花算法,复用已定义的snowflake生成器
keyGenerateStrategy:
column: order_id
keyGeneratorName: my_snowflake
# 绑定表配置:逻辑表逗号分隔告诉框架:shs_user 和 shs_order 分片键存在关联关系(user.id = order.user_id);
#执行 user LEFT JOIN order 时,框架自动按分片键过滤,只路由对应 1 个库,不会扫描全部分库;
bindingTables:
- shs_user,shs_order
# 自定义分片算法集合
shardingAlgorithms:
# 原有用户分库算法
shs_user_db_alg:
# 算法类型:INLINE 行内表达式(简单取模场景首选)
type: INLINE
# 算法参数配置
props:
# 分库表达式:id对2取模,结果0走m0库,结果1走m1库
algorithm-expression: m$->{id % 2}
# 原有用户分表算法
shs_user_tb_alg:
# 算法类型:INLINE行内表达式
type: INLINE
props:
# 分表表达式:id%2结果+1,取值1/2,对应表shs_user_1、shs_user_2
algorithm-expression: shs_user_$->{id % 2 + 1}
# ===================== 新增订单分片算法 =====================
# shs_order分库算法:按userId取模2分配m0/m1
shs_order_db_alg:
type: INLINE
props:
algorithm-expression: m$->{user_id % 2}
# shs_order分表算法:userId%2+1 得到1/2对应表后缀
shs_order_tb_alg:
type: INLINE
props:
algorithm-expression: shs_order_$->{user_id % 2 + 1}
# 主键生成器集合(不变,两张表共用同一个雪花生成器)
keyGenerators:
# 雪花算法生成器,名称snowflake
my_snowflake:
# 生成器类型:SNOWFLAKE雪花算法
type: SNOWFLAKE
# 雪花算法参数
props:
# 机器ID,单服务部署固定填1;集群多实例需分配不同0~31数字
worker-id: 1
五、java代码
1.主启动类
// 新增:扫描mapper接口所在包
@SpringBootApplication
@MapperScan("com.hx.shared.mapper")
public class SharedjDomeApplication {
public static void main(String[] args) {
SpringApplication.run(SharedjDomeApplication.class, args);
}
}
2.实体
java
@TableName("shs_order")
@Data
public class ShsOrder {
//雪花算法
@TableId(type=IdType.ASSIGN_ID)
private Long orderId;
private String shopName;
private Integer amount;
@TableField
private Long userId;
private Date createTime;
}
java
@TableName("shs_user")
@Data
public class ShsUser{
@TableId(type=IdType.ASSIGN_ID)
private Long id;
private String name;
private Integer sex;
private Date createTime;
}
3.mapper层
public interface ShsOrderMapper extends BaseMapper<ShsOrder> {
}
public interface ShsUserMapper extends BaseMapper<ShsUser> {
List<Map<String,Object>> selectUserOrderList();
}
4.mybatis.xml
java
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.hx.shared.mapper.ShsUserMapper">
<select id="selectUserOrderList" resultType="map">
select
t.*,t1.order_id,t1.amount
from shs_user t
left join shs_order t1 on t.id = t1.user_id
where t.create_time < '2026-07-23 16:07:53'
order by t.name desc
</select>
</mapper>
5.测试类
java
@SpringBootTest
class UserTest {
@Autowired
private ShsUserMapper shsUserMapper;
@Autowired
private ShsOrderMapper shsOrderMapper;
@Test
public void saveUser() {
for (int i = 0; i < 10; i++){
ShsUser u=new ShsUser();
u.setName("小张"+ i);
u.setSex(1);
u.setCreateTime(new Date());
shsUserMapper.insert(u);
ShsOrder o=new ShsOrder();
o.setShopName("鞋"+ i);
o.setAmount(100);
o.setUserId(u.getId());
o.setCreateTime(new Date());
shsOrderMapper.insert(o);
}
}
@Test
public void selectUser() {
List<ShsUser> list = shsUserMapper.selectList(null);
for (ShsUser u : list) {
System.out.println(u);
}
}
@Test
public void selectOrder() {
List<Map<String, Object>> list = shsUserMapper.selectUserOrderList();
System.out.println("===========================");
for (Map<String, Object> u : list) {
System.out.println(u.toString());
}
System.out.println("===========================");
}
}
六、执行后看效果
- 分库逻辑 :
id % 2- id 偶数 → 0 → m0 库 (shs_db0)
- id 奇数 → 1 → m1 库 (shs_db1)
- 分表逻辑 :
id % 2 +1- id%2=0 → 表 1;id%2=1 → 表 2
- 每个库都存在两张真实表:
shs_user_1、shs_user_2
- 总真实表:m0_1、m0_2、m1_1、m1_2 四张物理表,业务统一操作逻辑表
shs_user - 主键:雪花算法全局唯一 ID,worker-id 单机固定 1,集群多节点要区分避免 ID 重复
执行 saveUser 方法,查看效果,id%2=0的保存到了shs_db0.shs_user_1中

id%2=1的保存到了shs_db1.shs_user_2中

想要扩展更深入了解的自己去慢慢研究吧