news 2026/3/28 7:52:43

分库分表 Sharding-JDBC 从入门到精通:Spring Boot 实战详解(附完整代码)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
分库分表 Sharding-JDBC 从入门到精通:Spring Boot 实战详解(附完整代码)

视频看了几百小时还迷糊?关注我,几分钟让你秒懂!

在高并发、大数据量的业务场景中,单库单表很容易成为性能瓶颈。为了解决这个问题,“分库分表”成了后端开发绕不开的话题。而Sharding-JDBC(现更名为ShardingSphere-JDBC)作为 Apache 顶级项目,是 Java 生态中最主流的分库分表中间件之一。

本文将带你从零基础实战落地,使用Java + Spring Boot搭建一个完整的分库分表案例,并讲解为什么用、怎么用、反例避坑,让小白也能一目了然!


一、需求场景:为什么要分库分表?

📌 场景描述

假设你正在开发一个电商平台的订单系统:

  • 日均订单量:50万+
  • 单表数据量:超过 2000 万行
  • 查询变慢、写入延迟、备份困难、主从同步压力大……

这时候,单库单表已经扛不住了!

✅ 解决方案:分库分表

  • 分库(Database Sharding):把数据分散到多个数据库实例,减轻单库压力。
  • 分表(Table Sharding):把一张大表拆成多张小表,提升查询效率。

举个例子:1亿条订单数据 → 拆成 2 个库 × 4 张表 = 8 份,每份仅 1250 万条。


二、Sharding-JDBC 是什么?

Sharding-JDBC 是客户端直连数据库的轻量级 Java 框架,以JDBC 驱动的形式嵌入应用,对业务代码几乎无侵入。

  • ✅ 优点:轻量、高性能、无需额外部署中间件
  • ❌ 缺点:不支持跨库复杂 JOIN、事务需谨慎处理

它属于ShardingSphere生态的一部分,还有 Sharding-Proxy(代理模式)等,但 JDBC 模式最适合 Spring Boot 应用。


三、实战:Spring Boot + Sharding-JDBC 分库分表

1️⃣ 环境准备

  • JDK 17
  • Spring Boot 3.2.x
  • MySQL 8.0(本地或 Docker)
  • Maven

2️⃣ 数据库设计(模拟 2 库 4 表)

-- 创建两个数据库 CREATE DATABASE order_db_0; CREATE DATABASE order_db_1; -- 在每个库中创建两张订单表 USE order_db_0; CREATE TABLE t_order_0 (order_id BIGINT PRIMARY KEY, user_id BIGINT, amount DECIMAL(10,2)); CREATE TABLE t_order_1 (order_id BIGINT PRIMARY KEY, user_id BIGINT, amount DECIMAL(10,2)); USE order_db_1; CREATE TABLE t_order_0 (order_id BIGINT PRIMARY KEY, user_id BIGINT, amount DECIMAL(10,2)); CREATE TABLE t_order_1 (order_id BIGINT PRIMARY KEY, user_id BIGINT, amount DECIMAL(10,2));

分片规则:

  • 库分片键user_id % 2→ 决定进order_db_0还是order_db_1
  • 表分片键order_id % 2→ 决定进t_order_0还是t_order_1

3️⃣ Spring Boot 项目搭建

pom.xml 依赖
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.apache.shardingsphere</groupId> <artifactId>shardingsphere-jdbc-core-spring-boot-starter</artifactId> <version>5.4.0</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> </dependencies>

注意:ShardingSphere 5.x 起,包名从io.shardingsphere改为org.apache.shardingsphere

application.yml 配置(核心!)
spring: shardingsphere: # 数据源配置 datasource: names: ds0,ds1 ds0: type: com.zaxxer.hikari.HikariDataSource driver-class-name: com.mysql.cj.jdbc.Driver jdbc-url: jdbc:mysql://localhost:3306/order_db_0?useSSL=false&serverTimezone=Asia/Shanghai username: root password: your_password ds1: type: com.zaxxer.hikari.HikariDataSource driver-class-name: com.mysql.cj.jdbc.Driver jdbc-url: jdbc:mysql://localhost:3306/order_db_1?useSSL=false&serverTimezone=Asia/Shanghai username: root password: your_password # 分片规则 rules: sharding: tables: t_order: actual-data-nodes: ds$->{0..1}.t_order_$->{0..1} table-strategy: standard: sharding-column: order_id sharding-algorithm-name: table-inline database-strategy: standard: sharding-column: user_id sharding-algorithm-name: db-inline sharding-algorithms: db-inline: type: INLINE props: algorithm-expression: ds$->{user_id % 2} table-inline: type: INLINE props: algorithm-expression: t_order_$->{order_id % 2} # 打印 SQL(调试用) props: sql-show: true

4️⃣ 实体类与 Mapper

// Order.java public class Order { private Long orderId; private Long userId; private BigDecimal amount; // getter/setter... }
// OrderMapper.java(使用 MyBatis 或 JPA 均可,这里简化用 JdbcTemplate) @Repository public class OrderMapper { @Autowired private JdbcTemplate jdbcTemplate; public void insert(Order order) { String sql = "INSERT INTO t_order (order_id, user_id, amount) VALUES (?, ?, ?)"; jdbcTemplate.update(sql, order.getOrderId(), order.getUserId(), order.getAmount()); } public List<Order> findByUserId(Long userId) { String sql = "SELECT * FROM t_order WHERE user_id = ?"; return jdbcTemplate.query(sql, (rs, rowNum) -> new Order( rs.getLong("order_id"), rs.getLong("user_id"), rs.getBigDecimal("amount") ), userId); } }

注意:SQL 中写的是逻辑表名t_order,Sharding-JDBC 会自动路由到真实表。

5️⃣ 测试 Controller

@RestController public class OrderController { @Autowired private OrderMapper orderMapper; @PostMapping("/order") public String createOrder(@RequestBody Order order) { orderMapper.insert(order); return "Order inserted!"; } @GetMapping("/orders/{userId}") public List<Order> getOrders(@PathVariable Long userId) { return orderMapper.findByUserId(userId); } }

6️⃣ 测试效果

  • 插入userId=1001, orderId=10001
    user_id % 2 = 1→ 库ds1
    order_id % 2 = 1→ 表t_order_1
    ✅ 数据写入order_db_1.t_order_1

  • 查询userId=1001
    → 自动路由到ds1,并扫描t_order_0t_order_1(因为不知道 order_id)
    ✅ 返回所有该用户订单

控制台会打印实际执行的 SQL,验证是否命中正确库表。


四、反例 & 常见错误(避坑指南)

❌ 反例1:不分片键直接查全表

// 错误!没有分片键,会广播查询所有库所有表! List<Order> all = jdbcTemplate.query("SELECT * FROM t_order", ...);

后果:8 个表全查,性能爆炸!
✅ 正确做法:尽量带分片键(如user_id)查询。


❌ 反例2:跨库事务不处理

@Transactional public void transfer(Order order1, Order order2) { orderMapper.insert(order1); // 可能写入 ds0 orderMapper.insert(order2); // 可能写入 ds1 }

Sharding-JDBC 默认使用本地事务,跨库时无法保证 ACID!
✅ 解决方案:

  • 使用Seata等分布式事务框架
  • 或避免跨库写入(通过业务设计,如按 user_id 聚合)

❌ 反例3:ORDER BY / GROUP BY 跨分片性能差

SELECT user_id, SUM(amount) FROM t_order GROUP BY user_id;

如果user_id不是分片键,会从所有分片拉数据到内存聚合,OOM 风险!
✅ 建议:聚合操作尽量在单分片内完成,或使用异步数仓。


五、注意事项总结

项目说明
分片键选择必须高频查询字段,如 user_id、tenant_id
避免全表扫描不带分片键的查询慎用
事务范围跨库事务需额外处理
JOIN 限制仅支持同一分片内的表 JOIN
自增 ID建议用雪花算法(ShardingSphere 提供SNOWFLAKE算法)
版本兼容Spring Boot 3 + JDK 17 请用 ShardingSphere 5.3+

六、结语

分库分表不是银弹,但在数据量爆炸时是必经之路。Sharding-JDBC 以其轻量、易集成、高性能的特点,成为 Spring Boot 项目的首选方案。

只要掌握分片规则设计 + 避开跨库陷阱,你就能轻松驾驭千万级数据!

视频看了几百小时还迷糊?关注我,几分钟让你秒懂!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/27 6:51:19

企业网站制作公司对比:2026年十大靠谱网站建设公司盘点

在数字经济深度渗透的2026年&#xff0c;企业官网已从单纯的“线上名片”进化为承载品牌价值传递、用户精准转化与全链路数据沉淀的核心数字化阵地。面对AI智能交互、3D沉浸式体验、移动端优先等技术趋势&#xff0c;选择适配的网站建设服务商成为企业数字化转型的关键决策。本…

作者头像 李华
网站建设 2026/3/27 12:24:46

基于spring+vue的在线教育微信小程序[spring]-计算机毕业设计源码+LW文档

摘要&#xff1a;随着移动互联网的快速发展&#xff0c;在线教育作为一种新兴的教育模式受到广泛关注。微信小程序的普及为在线教育提供了新的平台和机遇。本文介绍了一个基于SpringVue框架的在线教育微信小程序的设计与实现。该系统利用Spring框架构建后端服务&#xff0c;提供…

作者头像 李华
网站建设 2026/3/27 17:13:00

导致BSCI认证不通过的问题有哪些?

BSCI验厂是由倡议商界遵守社会责任组织发起的一项全球供应链社会责任审核项目&#xff0c;旨在确保供应商遵守社会责任标准&#xff0c;包括遵守法律、尊重人权、保护劳工权益、确保工作环境安全健康等方面。BSCI验厂不通过&#xff0c;通常是因为劳工权益、安全卫生或管理体系…

作者头像 李华
网站建设 2026/3/27 10:06:22

2026必备!继续教育必看!9款AI论文工具深度测评

2026必备&#xff01;继续教育必看&#xff01;9款AI论文工具深度测评 2026年度学术写作工具测评&#xff1a;如何选到最适合你的AI助手 随着人工智能技术的不断进步&#xff0c;AI论文工具已经成为高校师生和研究人员不可或缺的得力助手。然而&#xff0c;面对市场上琳琅满目…

作者头像 李华
网站建设 2026/3/27 15:12:10

TERMUX黑客派:10个你意想不到的实战场景

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 创建一个TERMUX安全工具包&#xff0c;包含&#xff1a;1. 网络扫描器&#xff08;类似nmap&#xff09;2. WiFi分析模块 3. 加密通信隧道 4. 密码强度检测工具 5. 自动化漏洞扫描…

作者头像 李华
网站建设 2026/3/27 18:44:47

1小时打造自动刷新工具原型

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 快速开发一个自动刷新工具原型&#xff0c;核心功能&#xff1a;1. 最基本的时间设置&#xff1b;2. 开关控制&#xff1b;3. 当前状态显示。使用最简代码实现&#xff0c;不考虑异…

作者头像 李华