当前位置: 首页 > news >正文

SpringBoot 整合 Sharding-JDBC 全面教程:常用 API 串联与实战指南

《SpringBoot整合Sharding-JDBC全面教程:常用 API 串联与实战指南》

你想要在SpringBoot项目中规范、高效地整合Sharding-JDBC,掌握其分库分表、读写分离等核心功能的常用API,并遵循行业最佳实践,这份教程会帮你系统落地。

一、核心前置说明

1. 版本选型(最佳实践:选稳定兼容版)

  • JDK:1.8+(Sharding-JDBC 5.x对JDK8兼容性最好)
  • SpringBoot:2.7.x(避免3.x初期兼容性问题)
  • Sharding-JDBC:5.4.0(Apache ShardingSphere 5.x稳定版,含JDBC模块)

2. 依赖引入(Maven)

<dependencies><!-- SpringBoot核心 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- SpringBoot数据访问 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency><!-- Sharding-JDBC核心依赖 --><dependency><groupId>org.apache.shardingsphere</groupId><artifactId>shardingsphere-jdbc-core-spring-boot-starter</artifactId><version>5.4.0</version></dependency><!-- MySQL驱动 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope><version>8.0.33</version></dependency><!-- 数据源(HikariCP,SpringBoot默认,性能最优) --><dependency><groupId>com.zaxxer</groupId><artifactId>HikariCP</artifactId></dependency><!-- 测试 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies>

二、核心概念速览(新手必懂)

  • 分片键:用于分库/分表的字段(如订单ID、用户ID)
  • 分片策略:按规则将数据路由到指定库/表(如取模、范围、哈希)
  • 逻辑表:分表的抽象名称(如t_order),物理表是t_order_0t_order_1
  • 读写分离:主库写、从库读,Sharding-JDBC自动路由

三、实战场景1:单库分表(最常用)

1. 数据库准备

创建数据库demo_db,并创建2个订单分表:

CREATEDATABASEIFNOTEXISTSdemo_db;USEdemo_db;-- 订单逻辑表t_order的物理表:t_order_0、t_order_1CREATETABLEt_order_0(order_idBIGINTPRIMARYKEY,user_idINTNOTNULL,order_amountDECIMAL(10,2)NOTNULL,create_timeDATETIMEDEFAULTCURRENT_TIMESTAMP);CREATETABLEt_order_1(order_idBIGINTPRIMARYKEY,user_idINTNOTNULL,order_amountDECIMAL(10,2)NOTNULL,create_timeDATETIMEDEFAULTCURRENT_TIMESTAMP);

2. 核心配置(application.yml)

遵循最佳实践:配置分层清晰、策略明确、注释完整

spring:# Sharding-JDBC核心配置shardingsphere:# 数据源配置datasource:names:ds0# 数据源名称(单库)ds0:type:com.zaxxer.hikari.HikariDataSourcedriver-class-name:com.mysql.cj.jdbc.Driverurl:jdbc:mysql://localhost:3306/demo_db?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghaiusername:root# 替换为你的数据库账号password:root# 替换为你的数据库密码# 分库分表规则rules:sharding:# 分片表配置tables:t_order:# 逻辑表名actual-data-nodes:ds0.t_order_${0..1}# 物理表节点(ds0库下的t_order_0/1)# 分片策略:按order_id取模分表table-strategy:standard:sharding-column:order_id# 分片键sharding-algorithm-name:t_order_inline# 分片算法名称# 分片算法配置sharding-algorithms:t_order_inline:type:INLINE# 行内表达式算法(简单高效,适合取模/范围)props:algorithm-expression:t_order_${order_id % 2}# 算法规则:order_id%2决定表后缀# 属性配置:打印SQL(调试必备,生产可关闭)props:sql-show:true

3. 代码编写(最佳实践:分层解耦)

(1)实体类(Order.java)
importlombok.Data;importjavax.persistence.*;importjava.math.BigDecimal;importjava.time.LocalDateTime;@Data@Entity@Table(name="t_order")// 映射逻辑表名publicclassOrder{@IdprivateLongorderId;// 分片键:订单IDprivateIntegeruserId;// 用户IDprivateBigDecimalorderAmount;// 订单金额privateLocalDateTimecreateTime;// 创建时间}
(2)Repository(OrderRepository.java)
importorg.springframework.data.jpa.repository.JpaRepository;importorg.springframework.stereotype.Repository;@RepositorypublicinterfaceOrderRepositoryextendsJpaRepository<Order,Long>{// 继承JpaRepository,无需手写基础CRUD}
(3)Service(OrderService.java)
importorg.springframework.stereotype.Service;importjavax.annotation.Resource;importjava.util.List;@ServicepublicclassOrderService{@ResourceprivateOrderRepositoryorderRepository;// 新增订单(Sharding-JDBC自动路由到对应分表)publicOrdersaveOrder(Orderorder){returnorderRepository.save(order);}// 查询所有订单(Sharding-JDBC自动聚合所有分表数据)publicList<Order>listAllOrders(){returnorderRepository.findAll();}// 根据订单ID查询(Sharding-JDBC自动路由到对应分表)publicOrdergetOrderById(LongorderId){returnorderRepository.findById(orderId).orElse(null);}}
(4)测试类(ShardingJdbcDemoApplicationTests.java)
importorg.junit.jupiter.api.Test;importorg.springframework.boot.test.context.SpringBootTest;importjavax.annotation.Resource;importjava.math.BigDecimal;importjava.time.LocalDateTime;@SpringBootTestpublicclassShardingJdbcDemoApplicationTests{@ResourceprivateOrderServiceorderService;@TestpublicvoidtestSaveOrder(){// 测试订单1:orderId=1 → 路由到t_order_1Orderorder1=newOrder();order1.setOrderId(1L);order1.setUserId(1001);order1.setOrderAmount(newBigDecimal("99.99"));order1.setCreateTime(LocalDateTime.now());orderService.saveOrder(order1);// 测试订单2:orderId=2 → 路由到t_order_0Orderorder2=newOrder();order2.setOrderId(2L);order2.setUserId(1002);order2.setOrderAmount(newBigDecimal("199.99"));order2.setCreateTime(LocalDateTime.now());orderService.saveOrder(order2);// 查询验证System.out.println("订单1:"+orderService.getOrderById(1L));System.out.println("订单2:"+orderService.getOrderById(2L));System.out.println("所有订单:"+orderService.listAllOrders());}}

4. 运行结果验证

  • 控制台会打印Sharding-JDBC路由后的SQL,比如:
    INSERT INTO t_order_1 (order_id, user_id, order_amount, create_time) VALUES (1, 1001, 99.99, ...)
    INSERT INTO t_order_0 (order_id, user_id, order_amount, create_time) VALUES (2, 1002, 199.99, ...)
  • 数据库中t_order_1有订单1,t_order_0有订单2,查询时自动聚合结果。

四、实战场景2:分库分表(进阶)

若需按user_id分库、order_id分表,修改配置如下(核心变化):

spring:shardingsphere:datasource:names:ds0,ds1# 两个数据源(分库)ds0:type:com.zaxxer.hikari.HikariDataSourcedriver-class-name:com.mysql.cj.jdbc.Driverurl:jdbc:mysql://localhost:3306/demo_db_0?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghaiusername:rootpassword:rootds1:type:com.zaxxer.hikari.HikariDataSourcedriver-class-name:com.mysql.cj.jdbc.Driverurl:jdbc:mysql://localhost:3306/demo_db_1?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghaiusername:rootpassword:rootrules:sharding:tables:t_order:actual-data-nodes:ds${0..1}.t_order_${0..1}# 两个库,每个库2个表# 分库策略:按user_id取模database-strategy:standard:sharding-column:user_idsharding-algorithm-name:t_order_db_inline# 分表策略:按order_id取模table-strategy:standard:sharding-column:order_idsharding-algorithm-name:t_order_table_inlinesharding-algorithms:t_order_db_inline:type:INLINEprops:algorithm-expression:ds${user_id % 2}t_order_table_inline:type:INLINEprops:algorithm-expression:t_order_${order_id % 2}props:sql-show:true

五、实战场景3:读写分离(最佳实践:主从架构)

spring:shardingsphere:datasource:names:master,slave0# 主库+从库master:type:com.zaxxer.hikari.HikariDataSourcedriver-class-name:com.mysql.cj.jdbc.Driverurl:jdbc:mysql://localhost:3306/demo_db?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghaiusername:rootpassword:rootslave0:type:com.zaxxer.hikari.HikariDataSourcedriver-class-name:com.mysql.cj.jdbc.Driverurl:jdbc:mysql://localhost:3307/demo_db?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghaiusername:rootpassword:rootrules:readwrite-splitting:data-sources:demo_ds:# 读写分离数据源名称type:STATIC# 静态读写分离(固定主从)props:write-data-source-name:master# 写库read-data-source-names:slave0# 读库(多个用逗号分隔)load-balancer-name:round_robin# 负载均衡算法(轮询)load-balancers:round_robin:type:ROUND_ROBIN# 轮询算法(简单高效)props:sql-show:true

六、常用API与最佳实践

1. 自定义分片算法(进阶场景)

若内置算法不满足需求,可自定义分片算法:

importorg.apache.shardingsphere.sharding.api.sharding.standard.PreciseShardingAlgorithm;importorg.apache.shardingsphere.sharding.api.sharding.standard.PreciseShardingValue;importorg.springframework.stereotype.Component;importjava.util.Collection;// 自定义精确分片算法(按order_id范围分表)@ComponentpublicclassCustomOrderShardingAlgorithmimplementsPreciseShardingAlgorithm<Long>{@OverridepublicStringdoSharding(Collection<String>availableTargetNames,PreciseShardingValue<Long>shardingValue){LongorderId=shardingValue.getValue();// 自定义规则:order_id<1000 → t_order_0,否则→t_order_1if(orderId<1000){return"t_order_0";}else{return"t_order_1";}}}

配置中替换算法类型为CUSTOM,指定算法类:

sharding-algorithms:t_order_custom:type:CUSTOMprops:sharding-algorithm-class-name:com.example.demo.algorithm.CustomOrderShardingAlgorithm

2. 分布式ID生成(最佳实践:避免主键冲突)

Sharding-JDBC内置分布式ID生成器,配置如下:

spring:shardingsphere:rules:sharding:key-generators:snowflake:# 雪花算法(推荐)type:SNOWFLAKEprops:worker-id:1# 工作节点ID(集群需唯一)tables:t_order:key-generate-strategy:column:order_id# 主键字段key-generator-name:snowflake# 关联雪花算法

3. 最佳实践总结(避坑指南)

  • 分片键选择:优先选查询频繁、值均匀的字段(如订单ID),避免用范围字段(如时间)作为唯一分片键(易数据倾斜)。
  • 避免跨库/跨表JOIN:分库分表后JOIN性能极差,尽量通过业务设计规避。
  • 生产环境关闭sql-show:避免日志冗余,影响性能。
  • 事务支持:分库事务需用Sharding-JDBC的XA事务或BASE事务,单库事务无特殊配置。

七、核心测试与验证

  1. 功能验证:通过单元测试验证数据路由是否正确(如不同分片键的值是否落到指定库/表)。
  2. 性能验证:压测分库分表后的读写性能,对比单库单表(确保分片后性能提升)。
  3. 异常验证:测试分片键为空、值超出范围等场景,确保程序有异常处理。

总结

  1. SpringBoot整合Sharding-JDBC的核心是数据源配置+分片规则+算法配置,优先使用INLINE算法(简单高效),复杂场景自定义算法。
  2. 最佳实践:分片键选均匀字段、避免跨库JOIN、用雪花算法生成分布式ID、生产关闭SQL打印。
  3. 常见场景优先级:单库分表(入门)→ 分库分表(进阶)→ 读写分离(高可用),按需落地。
http://www.jsqmd.com/news/133923/

相关文章:

  • OPC UA 与 MQTT 如何配合?以DXPServer为例的边缘到云组合方式
  • 从+NV+Apex+到+Apex+for+Ascend:混合精度训练在昇腾平台的适配与编译全流程解析
  • 5、工作流开发:异常处理与内置活动扩展
  • 6、工作流开发:订单折扣计算与图书馆书籍预订通信实现
  • 用AIGC构建测试知识库:自动问答系统解答团队常见测试问题
  • 远程协作新方式:用GPT-SoVITS复刻团队成员声音
  • GPT-SoVITS + GPU加速:极致提升训练效率
  • 一年半前端码农一枚,被踩失业,已经躺平两个月了
  • 7、图书馆预订系统的工作流实现与应用
  • 大模型本身的测试难题:如何评估生成式AI的稳定性与一致性?
  • 硬件学习规划
  • 本地部署GPT-SoVITS:完全掌控你的语音数据
  • 丢了300万订单后,我才懂:老板会演说,客户才会签单,是真的吗?看完这篇你就明白了!
  • Open-AutoGLM一键部署方案出炉:支持多环境适配的工业级实践
  • 沃尔玛采购总被风控?合规账号体系才是破局关键
  • 如何评估GPT-SoVITS生成语音的质量?
  • 国产AI代理新突破,Open-AutoGLM 桌面代理为何突然引爆开发者圈?
  • AIGC输出的“幻觉”检测:为AI生成的测试用例设置可信度评分机制‌
  • 如何利用球幕影院提升观影体验与市场竞争力?
  • GPT-SoVITS训练过程可视化:理解模型收敛状态
  • Open-AutoGLM爬虫部署全流程:从环境搭建到高并发优化(稀缺实战文档)
  • 球幕影院是什么?9d裸眼轨道影院投资多少钱?
  • Open-AutoGLM性能优化全攻略(隐藏技巧+实战案例,稀缺资料流出)
  • 语音情绪表达增强:GPT-SoVITS未来发展方向
  • GPT-SoVITS支持长文本输入吗?使用经验分享
  • 测试报告自动生成:大模型将测试结果转化为业务可读的可视化摘要
  • Open-AutoGLM核心机制揭秘:5个你必须掌握的关键模块与应用场景
  • 毕业设计项目 基于机器视觉的行人口罩佩戴检测
  • 你还在写规则爬虫?Open-AutoGLM已实现全自动智能抓取(技术革命来了)
  • 实验室改造,这5个坑千万别踩!