springboot3集成shardingsphere4.0 分表分库

一、说明

版本选择很重要,切记,我使用的 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 &lt; '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("===========================");
    }

}
六、执行后看效果
  1. 分库逻辑id % 2
    • id 偶数 → 0 → m0 库 (shs_db0)
    • id 奇数 → 1 → m1 库 (shs_db1)
  2. 分表逻辑id % 2 +1
    • id%2=0 → 表 1;id%2=1 → 表 2
    • 每个库都存在两张真实表:shs_user_1shs_user_2
  3. 总真实表:m0_1、m0_2、m1_1、m1_2 四张物理表,业务统一操作逻辑表 shs_user
  4. 主键:雪花算法全局唯一 ID,worker-id 单机固定 1,集群多节点要区分避免 ID 重复

执行 saveUser 方法,查看效果,id%2=0的保存到了shs_db0.shs_user_1中

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

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

相关推荐
乐观的Terry1 小时前
9、发布系统-Webhook自动发布
java·spring boot·spring·spring cloud·mybatis
PH = 71 小时前
SpringBoot使用自动装配编写Start包
java·spring boot·后端
逆境不可逃1 小时前
Java JUC 同步工具类一次讲透:CountDownLatch、CyclicBarrier、Semaphore、Phaser 与 AQS 共享模式
java·开发语言·python
xlq223222 小时前
高并发服务器day5
java·服务器·数据库
our_times2 小时前
【硬核实战】当机器人走进厨房:Java后端如何重构物联网并发与状态一致性`。
java·重构·机器人
一路向北North2 小时前
Spring AI(5) :对话机器人-会话记忆
java·后端·spring
kingwebo'sZone2 小时前
C#事件声明办法
java·前端·c#
Q渡劫2 小时前
MinIO 从下载到集成 Spring Boot 完整教程
spring boot·spring·maven
冻感糕人~2 小时前
大模型学习指南:收藏这份AI Agent四层工程地图(小白程序员必备)
java·大数据·人工智能·学习·大模型·agent·大模型学习