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

简单实现shardingSphere + MybatisPlus分库分表2025

shardingSphere分库分表简单实现

  • 准备
    • 环境
    • Pom
  • 数据库准备
    • 订单-测试雪花算法Long主键
    • 任务-测试UUID算法String主键
  • 代码部分
    • 配置文件
      • application.yaml
      • sharding.yaml
    • 实体类
      • 订单
      • 任务
    • Mapper
    • Service
      • 订单服务
      • 任务服务
    • 雪花算法工具
    • UUID分库工具
    • UUID分表工具
  • 实测
    • 创建
    • 查询

准备

环境

  • mysql 5.7 +
  • Springboot 3.2 +
  • mybatis-plus 3.5.5
  • druid 1.2.23
  • shardingsphere-jdbc 5.5
  • JDK 21

Pom

<dependencies><!-- Spring Boot --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-spring-boot3-starter</artifactId><version>3.5.5</version></dependency><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><scope>runtime</scope></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.2.23</version></dependency><dependency><groupId>org.apache.shardingsphere</groupId><artifactId>shardingsphere-jdbc</artifactId><version>5.5.0</version><exclusions><exclusion><groupId>org.apache.shardingsphere</groupId><artifactId>shardingsphere-test-util</artifactId></exclusion></exclusions></dependency><dependency><groupId>com.alibaba.fastjson2</groupId><artifactId>fastjson2</artifactId><version>2.0.54</version></dependency>
</dependencies>

数据库准备

订单-测试雪花算法Long主键

新建两个库、分别建四张表

CREATE DATABASE `order_db_0` /*!40100 DEFAULT CHARACTER SET utf8 */;
CREATE DATABASE `order_db_1` /*!40100 DEFAULT CHARACTER SET utf8 */;CREATE TABLE `order_0` (`order_id` bigint(20) NOT NULL,`user_id` bigint(20) NOT NULL,`amount` decimal(10,2) NOT NULL,`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,PRIMARY KEY (`order_id`),KEY `idx_user_id` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- 其他四张表结构一致即可

任务-测试UUID算法String主键

CREATE DATABASE `correct_task_0` /*!40100 DEFAULT CHARACTER SET utf8 */;
---0-2建立三个库
CREATE TABLE `correct_main_task_0` (`trace_id` varchar(255) NOT NULL COMMENT '主键',`task_type` varchar(16) NOT NULL COMMENT '任务类型',`task_status` varchar(16) NOT NULL COMMENT '任务状态',`task_stage` varchar(16) NOT NULL COMMENT '任务阶段',`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,PRIMARY KEY (`trace_id`),KEY `timer_idx` (`create_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--0-4建立五张表

代码部分

配置文件

在resource目录下新建两个文件:

application.yaml

spring:main:allow-bean-definition-overriding: trueapplication:name: ls-backenddatasource:driver-class-name: org.apache.shardingsphere.driver.ShardingSphereDriverurl: jdbc:shardingsphere:classpath:sharding.yamlservlet:multipart:max-file-size: 100MBmax-request-size: 100MB
server:port: 8085servlet:context-path: /encoding:force-response: true#Mybatis扫描
mybatis:config-location: classpath:/mybatis-config.xmlmybatis-plus:mapper-locations: classpath:/mapper/*Mapper.xmlconfiguration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

sharding.yaml

dataSources:ds0:driverClassName: com.mysql.cj.jdbc.DriverdataSourceClassName: com.alibaba.druid.pool.DruidDataSourceurl: jdbc:mysql://xxxusername: testpassword: testds1:driverClassName: com.mysql.cj.jdbc.DriverdataSourceClassName: com.alibaba.druid.pool.DruidDataSourceurl: jdbc:mysql://yyyusername: testpassword: testct0:driverClassName: com.mysql.cj.jdbc.DriverdataSourceClassName: com.alibaba.druid.pool.DruidDataSourceurl: jdbc:mysql://zzzusername: testpassword: testct1:driverClassName: com.mysql.cj.jdbc.DriverdataSourceClassName: com.alibaba.druid.pool.DruidDataSourceurl: jdbc:mysql://qqqusername: testpassword: testct2:driverClassName: com.mysql.cj.jdbc.DriverdataSourceClassName: com.alibaba.druid.pool.DruidDataSourceurl: jdbc:mysql://wwwusername: testpassword: testrules:- !SHARDINGtables:order:actualDataNodes: ds${0..1}.order_${0..3}tableStrategy:standard:shardingColumn: order_idshardingAlgorithmName: order-id-inlinedatabaseStrategy:standard:shardingColumn: user_idshardingAlgorithmName: db-inlinecorrect_main_task:actualDataNodes: ct${0..2}.correct_main_task_${0..4}tableStrategy:standard:shardingColumn: trace_idshardingAlgorithmName: trace-id-tb-inlinedatabaseStrategy:standard:shardingColumn: trace_idshardingAlgorithmName: trace-id-db-inlinebindingTables:- order- correct_main_taskshardingAlgorithms:db-inline:type: INLINEprops:algorithm-expression: ds${user_id % 2}order-id-inline:type: INLINEprops:algorithm-expression: order_${order_id % 4}trace-id-tb-inline:type: CLASS_BASEDprops:strategy: STANDARDalgorithmClassName: com.test.util.MainTaskTbSplittrace-id-db-inline:type: CLASS_BASEDprops:strategy: STANDARDalgorithmClassName: com.test.util.MainTaskDbSplitprops:sql-show: true

实体类

订单

@Data
@TableName("`order`") // MyBatis-Plus 表名(与分片表名一致)
public class Order {@TableId(type = IdType.ASSIGN_ID) // 手动输入主键(由雪花算法生成)private Long orderId; private Long userId;private BigDecimal amount;private LocalDateTime createTime;
}

任务

@Data
@TableName("`correct_main_task`") // MyBatis-Plus 表名(与分片表名一致)
public class CorrectMainTask {@TableId(type = IdType.ASSIGN_ID) // 手动输入主键(由雪花算法生成)private String traceId;private String taskType;private String taskStatus;private String taskStage;private Date createTime;private Date updateTime;
}

Mapper

@Mapper
public interface OrderMapper extends BaseMapper<Order> {
}@Mapper
public interface CorrectMainTaskMapper extends BaseMapper<CorrectMainTask> {
}

Service

订单服务

@Service
@Slf4j
public class OrderService {@Autowiredprivate OrderMapper orderMapper;@Transactionalpublic int createOrder(Long userId, BigDecimal amount) {SnowflakeIdGenerator generator = new SnowflakeIdGenerator(1, 1);Order order = new Order();order.setOrderId(generator.nextId()); // 自动生成 BIGINT 类型的雪花 IDorder.setUserId(userId);order.setAmount(amount);log.info("即将插入的order: {}", JSON.toJSONString(order));// MyBatis-Plus 插入return orderMapper.insert(order);}public List<Order> getOrderById(Long orderId, Long userId) {log.info("查询订单,orderId: {}", orderId);QueryWrapper<Order> wrapper = new QueryWrapper<>();wrapper.eq("user_id", userId);wrapper.eq("order_id", orderId);return orderMapper.selectList(wrapper);}
}

任务服务

@Service
public class CorrectMainTaskService {@Autowiredprivate CorrectMainTaskMapper correctMainTaskMapper;@Transactionalpublic CorrectMainTask creat() {CorrectMainTask correctMainTask = new CorrectMainTask();correctMainTask.setTraceId(UUID.randomUUID().toString());correctMainTask.setTaskType("testType" + randomTwoDigit());correctMainTask.setTaskStatus("testStatus" + randomTwoDigit());correctMainTask.setTaskStage("testStage" + randomTwoDigit());correctMainTask.setCreateTime(new Date());correctMainTask.setUpdateTime(new Date());int insert = correctMainTaskMapper.insert(correctMainTask);if (insert > 0) {return correctMainTask;}return null;}public CorrectMainTask get(String traceId) {return correctMainTaskMapper.selectById(traceId);}public static String randomTwoDigit() {return String.valueOf(new java.util.Random().nextInt(100));}
}

雪花算法工具

public class SnowflakeIdGenerator {// 起始时间戳(2024-01-01 00:00:00)private static final long TWEPOCH = 1704067200000L;// 工作机器 ID(10位,范围:0~1023)private final long workerId;// 数据中心 ID(10位中的高位,范围:0~1023)private final long datacenterId;// 序列号(12位,范围:0~4095)private long sequence = 0L;// 上次生成 ID 的时间戳(毫秒)private long lastTimestamp = -1L;/*** 构造函数(需指定唯一的工作机器 ID 和数据中心 ID)* @param workerId 工作机器 ID(0~1023)* @param datacenterId 数据中心 ID(0~1023)*/public SnowflakeIdGenerator(long workerId, long datacenterId) {// 校验参数范围if (workerId > 1023 || workerId < 0) {throw new IllegalArgumentException("Worker ID must be between 0 and 1023");}if (datacenterId > 1023 || datacenterId < 0) {throw new IllegalArgumentException("Datacenter ID must be between 0 and 1023");}this.workerId = workerId;this.datacenterId = datacenterId;}/*** 生成下一个 ID* @return 64位 BIGINT 类型的雪花算法 ID*/public synchronized long nextId() {long timestamp = System.currentTimeMillis();// 处理时间戳回拨(可选)if (timestamp < lastTimestamp) {throw new RuntimeException("Clock moved backwards. Refusing to generate ID");}// 同一毫秒内生成多个 IDif (timestamp == lastTimestamp) {sequence = (sequence + 1) & 0xFFF; // 12位掩码(0~4095)if (sequence == 0) { // 序列号溢出,等待下一毫秒timestamp = waitNextMillis(lastTimestamp);}} else {sequence = 0L; // 新毫秒,序列号重置}lastTimestamp = timestamp;// 计算 ID(按位拼接)return ((timestamp - TWEPOCH) << 22) // 时间戳(41位)| (datacenterId << 17)       // 数据中心 ID(5位)| (workerId << 12)           // 工作机器 ID(5位)| sequence;                  // 序列号(12位)}/*** 等待下一毫秒(解决同一毫秒内序列号溢出)*/private long waitNextMillis(long lastTimestamp) {long timestamp = System.currentTimeMillis();while (timestamp <= lastTimestamp) {timestamp = System.currentTimeMillis();}return timestamp;}// 测试示例public static void main(String[] args) {// 示例:工作机器 ID=1,数据中心 ID=1(需根据实际环境调整)SnowflakeIdGenerator generator = new SnowflakeIdGenerator(1, 1);for (int i = 0; i < 10; i++) {System.out.println("Generated ID: " + generator.nextId());}}
}

UUID分库工具

public class MainTaskDbSplit implements StandardShardingAlgorithm<String> {@Overridepublic String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<String> shardingValue) {String value = shardingValue.getValue();char lastChar = Character.toLowerCase(value.charAt(value.length() - 1));int idx;if (lastChar >= '0' && lastChar <= '9') {idx = lastChar - '0' + 26;} else if (lastChar >= 'a' && lastChar <= 'z') {idx = lastChar - 'a';} else {idx = 0;}int targetIdx = idx % 3; // 均分到3个库List<String> sortedTargets = new ArrayList<>(availableTargetNames);sortedTargets.sort(String::compareTo);return sortedTargets.get(targetIdx);}@Overridepublic Collection<String> doSharding(Collection<String> availableTargetNames, RangeShardingValue<String> rangeShardingValue) {// 范围查询时,简单返回所有库return availableTargetNames;}}

UUID分表工具

public class MainTaskTbSplit implements StandardShardingAlgorithm<String> {@Overridepublic String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<String> shardingValue) {String value = shardingValue.getValue();char lastChar = Character.toLowerCase(value.charAt(value.length() - 1));int idx;if (lastChar >= '0' && lastChar <= '9') {idx = lastChar - '0' + 26;} else if (lastChar >= 'a' && lastChar <= 'z') {idx = lastChar - 'a';} else {idx = 0;}int targetIdx = idx % 5; // 均分到5个表List<String> sortedTargets = new ArrayList<>(availableTargetNames);sortedTargets.sort(String::compareTo);return sortedTargets.get(targetIdx);}@Overridepublic Collection<String> doSharding(Collection<String> availableTargetNames, RangeShardingValue<String> rangeShardingValue) {// 范围查询时,简单返回所有库return availableTargetNames;}
}

实测

创建

 INFO 35088 --- [ls-backend] [nio-8085-exec-1] ShardingSphere-SQL                       : Logic SQL: INSERT INTO `order`  ( order_id, user_id, amount )  VALUES (  ?, ?, ?  )
INFO 35088 --- [ls-backend] [nio-8085-exec-1] ShardingSphere-SQL                       : Actual SQL: ds1 ::: INSERT INTO `order_0`  ( order_id, user_id, amount )  VALUES (?, ?, ?) ::: [191145194425552896, 987654321095, 8]

查询

INFO 35088 --- [ls-backend] [nio-8085-exec-3] ShardingSphere-SQL                       : Logic SQL: SELECT  order_id,user_id,amount,create_time  FROM `order`      WHERE  (user_id = ? AND order_id = ?)
INFO 35088 --- [ls-backend] [nio-8085-exec-3] ShardingSphere-SQL                       : Actual SQL: ds1 ::: SELECT  order_id,user_id,amount,create_time  FROM `order_0`      WHERE  (user_id = ? AND order_id = ?) ::: [987654321095, 191145194425552896]

相关文章:

  • 【期末速成】软件项目管理
  • java使用WebMagic架构写个分布式爬虫
  • MySQL中触发器详解 触发器在自动化任务中的应用场景
  • 今日行情明日机会——20250611
  • 缓冲区(C语言缓冲区+内核缓冲区)一个例子解释他们的关系和作用!!!
  • TF-IDF算法的代码实践应用——关键词提取、文本分类、信息检索
  • AI时代的弯道超车之第二十五章:《生命3.0》未来AI有生命了怎么办?
  • Vuex 中Mutation 和Action介绍
  • Python环境搭建竞赛技术
  • wordpress搬家 数据库备份迁移
  • 大模型Transformer触顶带来的“热潮退去”,稀疏注意力架构创新或是未来
  • STM32外设学习之ADC
  • HNCTF2025 - Misc、Osint、Crypto WriteUp
  • 日语学习-日语知识点小记-进阶-JLPT-真题训练-N2阶段(1):单词部分练习
  • Linux操作系统基线检查与安全加固概述
  • 《HarmonyOSNext终极UIAbility手册:从启动模式到页面跳转,一网打尽!》
  • C++之前向声明
  • [学习] Costas环详解:从原理到实战
  • 2025GEO供应商排名深度解析:源易信息构建AI生态优势
  • 一数一源一标准的补充
  • 免费广告行业网站建设/百度网页入口
  • 贸易公司寮步网站建设哪家好/web网页制作教程
  • 网站开发用什么系统/北京网站建设公司哪家好
  • 顶尖手机网站建设/小网站关键词搜什么
  • 网站建设的基础常识/软件推广方案经典范文
  • 衡水网站网站建设/百度点击软件还有用吗