开发者

Spring Boot 3整合ShardingSphere-Jdbc分库分表实战

目录
  • 1. Maven 依赖
  • 2. application.yml 配置
    • 官网上是这么说的:
  • 3. 配置要点
    • 4. 数据库
      • 4. 常见问题
        • 5. 测试
          • 1. 测试普通表插入
          • 2. 测试普通表查询
          • 3. 测试users表插入
          • 4. 测试users表查询

        网上找了很多资料,包括官网,使用springboot3shardingsphere-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文件
        
        

        目录结构:

        Spring Boot 3整合ShardingSphere-Jdbc分库分表实战

        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_0users_1

        • 普通表:通过 !SINGLE 指定默认走 readwrite_ds,避免 TableNotFoundException

        • 元数据模式repository: MEMORY → 元数据存放在内存中,开发环境方便测试。

        4. 数据库

        数据库首先必须配置主从同步,最好从库禁用插入(这里教程很多,网上自己搭建)

        首先有2个数据源,一共4个库

        tsuki-chat是我的普通表库,用于存放不用分库分表的库

        tsuki-users是我的分库分表库,用于users表分表

        Spring Boot 3整合ShardingSphere-Jdbc分库分表实战

        users分库分表(我有两张表)

        Spring Boot 3整合ShardingSphere-Jdbc分库分表实战

        4. 常见问题

        1. 报错 TableNotFoundException → 没有配置 !SINGLE,需要为非分片表指定默认数据源。
        2. 事务中读操作跑到从库 → 配置 transactionalReadQueryStrategy: PRIMARY,保证事务一致性。
        3. 测试数据回滚导致表为空 → 注意是否加了 @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

        同时从库也有了数据

        Spring Boot 3整合ShardingSphere-Jdbc分库分表实战

        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

        同时从库也有了数据

        Spring Boot 3整合ShardingSphere-Jdbc分库分表实战

        Spring Boot 3整合ShardingSphere-Jdbc分库分表实战

        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   : 1756882805958

        2025-09-03T15:07:54.484+08:00  INFO 25284 --- [           main] c.t.c.server.TestChatServerApplication   : 1756882805960

        2025-09-03T15:07:54.484+08:00  INFO 25284 --- [           main] c.t.c.server.TestChatServerApplication   : 1756882805962

        2025-09-03T15:07:54.484+08:00  INFO 25284 --- [           main] c.t.c.server.TestChatServerApplication   : 1756882805964

        2025-09-03T15:07:54.484+08:00  INFO 25284 --- [           main] c.t.c.server.TestChatServerApplicatiojsn   : 1756882805966

        2025-09-03T15:07:54.484+08:00  INFO 25284 --- [           main] c.t.c.server.TestChatServerApplication   : 1756882805961

        2025-09-03T15:07:54.484+08:00  INFO 25284 --- [           main] c.t.c.server.TestChatServerApplication   : 1756882805963

        2025-09-03T15:07:54.484+08:00  INFO 25284 --- [           main] c.t.c.server.TestChatServerApplication   : 1756882805965

        我们可以看到输出了Actual SQL: users_slave ::: SELECT ,说明读取走了users_slave

        ✅ 这样配置后:

        • users 表支持 分库 + 分表 + 读写分离
        • testorders 等普通表支持 全局读写分离
        • SQL 路由清晰可控,适合生产环境逐步扩展。

        到此这篇关于Spring Boot 3整合ShardingSphere-Jdbc分库分表实战的文章就介绍到这了,更多相关Spring Boot 3 ShardingSphere-Jdbc分库分表内容请搜索编程客栈(www.devze.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程客栈(www.devze.com)!

        0

        上一篇:

        下一篇:

        精彩评论

        暂无评论...
        验证码 换一张
        取 消

        最新开发

        开发排行榜