Sharding-JDBC 5.4.1+SpringBoot3.4.1+MySQL8.4.1 使用案例

最近在升级 SpringBoot 项目,原版本是 2.7.16,要升级到 3.4.0 ,JDK 版本要从 JDK8 升级 JDK21,原项目中使用了 Sharding-JDBC,版本 4.0.0-RC1,在升级 SpringBoot 版本到 3.4.0 之后,服务启动失败,因此选择升级 Sharding-JDBC,记录代码如下:

环境

SpringBoot 3.4.1
Sharding-JDBC 5.4.1
MySQL 8.4.1

代码实现

下面通过代码实现,根据年份分表,2020 年之前数据一张表,之后每 2 年一张表。

准备测试数据 SQL

create table t_order
(id          int auto_incrementprimary key,order_id    varchar(36)                        null comment '订单ID',amount      decimal(18, 2)                     null comment '金额',order_year  int                                null comment '订单年份,用来作为分表字段',create_time datetime default CURRENT_TIMESTAMP null,update_time datetime default CURRENT_TIMESTAMP null on update CURRENT_TIMESTAMP,is_del      bit                                null
)comment '逻辑表,该表没有数据,但是没有这张表,sharding-jdbc执行时会报错';create table t_order_0
(id          int auto_incrementprimary key,order_id    varchar(36)                        null comment '订单ID',amount      decimal(18, 2)                     null comment '金额',order_year  int                                null comment '订单年份,用来作为分表字段',create_time datetime default CURRENT_TIMESTAMP null,update_time datetime default CURRENT_TIMESTAMP null on update CURRENT_TIMESTAMP,is_del      bit                                null
)comment '2020年以前的订单数据';create table t_order_2020
(id          int auto_incrementprimary key,order_id    varchar(36)                        null comment '订单ID',amount      decimal(18, 2)                     null comment '金额',order_year  int                                null comment '订单年份,用来作为分表字段',create_time datetime default CURRENT_TIMESTAMP null,update_time datetime default CURRENT_TIMESTAMP null on update CURRENT_TIMESTAMP,is_del      bit                                null
)comment '2020、2021年的订单数据';create table t_order_2022
(id          int auto_incrementprimary key,order_id    varchar(36)                        null comment '订单ID',amount      decimal(18, 2)                     null comment '金额',order_year  int                                null comment '订单年份,用来作为分表字段',create_time datetime default CURRENT_TIMESTAMP null,update_time datetime default CURRENT_TIMESTAMP null on update CURRENT_TIMESTAMP,is_del      bit                                null
)comment '2021、2022年的订单数据';create table t_order_2024
(id          int auto_incrementprimary key,order_id    varchar(36)                        null comment '订单ID',amount      decimal(18, 2)                     null comment '金额',order_year  int                                null comment '订单年份,用来作为分表字段',create_time datetime default CURRENT_TIMESTAMP null,update_time datetime default CURRENT_TIMESTAMP null on update CURRENT_TIMESTAMP,is_del      bit                                null
)comment '2023、2024年的订单数据';INSERT INTO db2025.t_order_2022 (order_id, amount, order_year) VALUES ('76cfe091-d87f-11ef-b84b-0242ac110002', 7777.13, 2022);
INSERT INTO db2025.t_order_2024 (order_id, amount, order_year) VALUES ('76d66bb8-d87f-11ef-b84b-0242ac110002', 3106.80, 2023);

搭建 SpringBoot 项目
pom.xml

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.4.1</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.wheelmouse</groupId><artifactId>sharding-sphere-case</artifactId><version>0.0.1-SNAPSHOT</version><name>sharding-sphere-case</name><description>sharding-sphere-case</description><url/><licenses><license/></licenses><developers><developer/></developers><scm><connection/><developerConnection/><tag/><url/></scm><properties><java.version>21</java.version><shardingsphere.version>5.4.1</shardingsphere.version><mybatis-plus.version>3.5.9</mybatis-plus.version></properties><dependencies><dependency><groupId>org.apache.shardingsphere</groupId><artifactId>shardingsphere-jdbc-core</artifactId><version>${shardingsphere.version}</version><exclusions><exclusion><groupId>org.yaml</groupId><artifactId>snakeyaml</artifactId></exclusion></exclusions></dependency><!-- 版本冲突	--><dependency><groupId>org.yaml</groupId><artifactId>snakeyaml</artifactId><version>1.33</version></dependency><dependency><groupId>javax.xml.bind</groupId><artifactId>jaxb-api</artifactId><version>2.3.1</version> <!-- 根据你的Java版本选择合适的版本 --></dependency><dependency><groupId>org.glassfish.jaxb</groupId><artifactId>jaxb-runtime</artifactId><version>2.3.1</version> <!-- 根据你的Java版本选择合适的版本 --></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jdbc</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- MyBatis-Plus --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.7</version></dependency><!-- Mybatis的分页插件 --><dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper-spring-boot-starter</artifactId><version>1.3.0</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><!-- MyBatis-Plus --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-spring-boot3-starter</artifactId><version>${mybatis-plus.version}</version></dependency><!-- 于 v3.5.9 起,PaginationInnerInterceptor 已分离出来。如需使用,则需单独引入 mybatis-plus-jsqlparser 依赖,jdk 11+ 引入可选模块 --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-jsqlparser</artifactId><version>${mybatis-plus.version}</version></dependency><!-- Mybatis的分页插件, --><dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper-spring-boot-starter</artifactId><version>1.3.0</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><configuration><annotationProcessorPaths><path><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></path></annotationProcessorPaths></configuration></plugin><plugin><groupId>org.graalvm.buildtools</groupId><artifactId>native-maven-plugin</artifactId></plugin><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><excludes><exclude><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></exclude></excludes></configuration></plugin></plugins></build></project>

Mapper

/**
* @author 重楼
* @description 针对表【t_order】的数据库操作Mapper
* @createDate 2025-01-23 12:55:01
* @Entity generator.domain.Order0
*/
public interface OrderMapper extends BaseMapper<Order> {}

Mapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.wheelmouse.shardingsphere.mapper.OrderMapper"><resultMap id="BaseResultMap" type="com.wheelmouse.shardingsphere.domain.Order"><id property="id" column="id" jdbcType="INTEGER"/><result property="orderId" column="order_id" jdbcType="VARCHAR"/><result property="amount" column="amount" jdbcType="DECIMAL"/><result property="orderYear" column="order_year" jdbcType="INTEGER"/><result property="createTime" column="create_time" jdbcType="TIMESTAMP"/><result property="updateTime" column="update_time" jdbcType="TIMESTAMP"/><result property="isDel" column="is_del" jdbcType="BIT"/></resultMap><sql id="Base_Column_List">id,order_id,amount,order_year,create_time,update_time,is_del</sql>
</mapper>

Service

/**
* @author 重楼
* @description 针对表【t_order】的数据库操作Service
* @createDate 2025-01-23 12:55:01
*/
public interface OrderService extends IService<Order> {}

ServiceImpl

/**
* @author 重楼
* @description 针对表【t_order】的数据库操作Service实现
* @createDate 2025-01-23 12:55:01
*/
@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order>implements OrderService {}

以下是Sharding-jdbc的配置类,Sharding-jdbc支持yaml和java 2中方式配置,这里采用java方式配置
ShardingConfig

/*** @author 重楼* @date 2025/1/14* @apiNote*/
@Configuration
public class ShardingConfig {@Beanpublic DataSource dataSource() throws SQLException {// 配置数据源Map<String, DataSource> dataSourceMap = new HashMap<>();dataSourceMap.put("ds0", createDataSource("com.mysql.cj.jdbc.Driver","jdbc:mysql://localhost:3306/db2025?serverTimezone=UTC&useSSL=false", // MySQL URL"root", // 用户名"123456" // 密码));// 这里的案例是单库,所以没有做读个数据源配置//dataSourceMap.put("ds1", createDataSource("com.mysql.cj.jdbc.Driver",//        "jdbc:mysql://127.0.0.1:3306/db2025?characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true", // MySQL URL//        "root", // 用户名//        "123456" // 密码//));// 配置 Sharding-JDBC 的分片规则ShardingRuleConfiguration shardingRuleConfig = new ShardingRuleConfiguration();shardingRuleConfig.getTables().add(getOrderTableRuleConfiguration());// 注册自定义分片算法// algorithmName 由用户指定,需要和分片策略中的分片算法一致// type 和 props,请参考分片内置算法:https://shardingsphere.apache.org/document/current/cn/user-manual/common-config/builtin-algorithm/sharding/Properties shardingAlgorithmProps = new Properties();shardingAlgorithmProps.setProperty("strategy", "COMPLEX"); // 指定算法类型shardingAlgorithmProps.setProperty("algorithmClassName", MyComplexKeysShardingAlgorithm.class.getName());shardingRuleConfig.getShardingAlgorithms().put("my-complex-keys-sharding-algorithm",new AlgorithmConfiguration("CLASS_BASED", shardingAlgorithmProps));// 创建 ShardingSphere 数据源Properties properties = new Properties();properties.put("sql-show", true);return ShardingSphereDataSourceFactory.createDataSource(dataSourceMap,Collections.singleton(shardingRuleConfig), properties);}private ShardingTableRuleConfiguration getOrderTableRuleConfiguration() {// 配置表规则ShardingTableRuleConfiguration tableRuleConfig = new ShardingTableRuleConfiguration("t_order", // 逻辑表名"ds0.t_order_${[" + orderActualDataNodes() + "]}" // 实际数据节点);// 配置复合分片策略tableRuleConfig.setTableShardingStrategy(new ComplexShardingStrategyConfiguration("order_year", // 分片键"my-complex-keys-sharding-algorithm" // 自定义分片算法名称));return tableRuleConfig;}/*** 自己实现,这里演示所以写死表名* @return*/private String orderActualDataNodes(){return "0,2020,2022,2024";}private DataSource createDataSource(final String driverClassName,final String url, final String username, final String password) {HikariDataSource dataSource = new HikariDataSource();dataSource.setDriverClassName(driverClassName);dataSource.setJdbcUrl(url); // MySQL 连接 URLdataSource.setUsername(username); // 数据库用户名dataSource.setPassword(password); // 数据库密码dataSource.setMaximumPoolSize(10); // 连接池最大连接数dataSource.setMinimumIdle(2); // 连接池最小空闲连接数dataSource.setIdleTimeout(30000); // 空闲连接超时时间dataSource.setMaxLifetime(1800000); // 连接最大存活时间dataSource.setConnectionTimeout(30000); // 连接超时时间return dataSource;}}

自定义分片算法实现类

/*** @author 重楼* @date 2025/1/10* @apiNote*/
@Component
public class MyComplexKeysShardingAlgorithm implements ComplexKeysShardingAlgorithm<String> {private static final Logger LOGGER = LoggerFactory.getLogger(MyComplexKeysShardingAlgorithm.class);@Overridepublic Collection<String> doSharding(Collection<String> availableTargetNames, ComplexKeysShardingValue<String> shardingValue) {Map<String, Collection<String>> columnNameAndShardingValuesMap = shardingValue.getColumnNameAndShardingValuesMap();// 获取 列名-值-方式1,范围查询Map<String, Range<String>> columnNameAndRangeValuesMap = shardingValue.getColumnNameAndRangeValuesMap();boolean hasDateYear = columnNameAndRangeValuesMap.containsKey("order_year");if (!hasDateYear) {return Lists.newArrayList();}Range<String> orderYear = columnNameAndRangeValuesMap.get("order_year");String orderIdUpperValue = orderYear.upperEndpoint();// 上限String orderIdLowerValue = orderYear.lowerEndpoint();// 下限String tablePrefix = "t_order";// 根据年份拼接物理表表名List<String> actualTableList = Lists.newArrayList();for (int dateYear = Integer.parseInt(orderIdLowerValue); dateYear <= Integer.parseInt(orderIdUpperValue); dateYear++) {// 如果交易年份小于2020则使用t_order_0,如果交易时间大于当前年则忽略//按照不同时间类型分的表  两年一张,小于2020年以前的数据数据都放在_0结尾的表中if (dateYear < 2020) {actualTableList.add(tablePrefix  + "_0");continue;}if (dateYear > Year.now().getValue()) {continue;}// 计算年份落在哪个时间分片键上int yearSharding = dateYear - (dateYear % 2);actualTableList.add(tablePrefix + "_" + yearSharding);}actualTableList = actualTableList.stream().distinct().collect(Collectors.toList());LOGGER.info("actual table name is :{}", actualTableList);return actualTableList;}

通过SPI的方式注册该算法,在 resources 文件夹下创建文件夹 META-INF/services。 在该文件夹下创建文件 org.apache.shardingsphere.sharding.spi.ShardingAlgorithm, 文件内写上我们自定义的分片算法。

com.wheelmouse.shardingsphere.config.MyComplexKeysShardingAlgorithm

测试类

@SpringBootTest
class ShardingSphereCaseApplicationTests {private final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");@Autowiredprivate OrderMapper orderMapper;@Testvoid list() {QueryWrapper<Order> queryWrapper = new QueryWrapper<>();queryWrapper.between("order_year", "2022", "2024");List<Order> list = orderMapper.selectList(queryWrapper);for (Order order : list) {System.out.println(order);}}}

结果:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/68993.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

WPS计算机二级•幻灯片的基础操作

听说这是目录哦 PPT的正确制作步骤&#x1f6e3;️认识PPT界面布局&#x1f3dc;️PPT基础操作 快捷键&#x1f3de;️制作PPT时 常用的快捷技巧&#x1f3d9;️快速替换PPT的 文本字体&#x1f303;快速替换PPT 指定文本内容&#x1f305;能量站&#x1f61a; PPT的正确制作步…

easyexcel读取写入excel easyexceldemo

1.新建springboot项目 2.添加pom依赖 <name>excel</name> <description>excelspringboot例子</description><parent> <groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId&…

Neural networks 神经网络

发展时间线 基础概念 多层神经网络结构 神经网络中一个网络层的数学表达 TensorFlow实践 创建网络层 神经网络的创建、训练与推理 推理 推理可以理解为执行一次前向传播 前向传播 前向传播直观数学表达 前向传播直观数学表达的Python实现 前向传播向量化实现 相关数学知识…

AR智慧点巡检系统探究和技术方案设计

一、项目背景 随着工业生产规模的不断扩大和设备复杂度的提升&#xff0c;传统的人工点巡检方式效率低下、易出错&#xff0c;难以满足现代化企业对设备运行可靠性和安全性的要求。AR&#xff08;增强现实&#xff09;技术的发展为点巡检工作带来了新的解决方案&#xff0c;通…

AI如何帮助解决生活中的琐碎难题?

引言&#xff1a;AI已经融入我们的日常生活 你有没有遇到过这样的情况——早上匆忙出门却忘了带钥匙&#xff0c;到了公司才想起昨天的会议资料没有打印&#xff0c;或者下班回家还在纠结晚饭吃什么&#xff1f;这些看似微不足道的小事&#xff0c;往往让人疲惫不堪。而如今&a…

用Python绘制一只懒羊羊

目录 一、准备工作 二、Turtle库简介 三、绘制懒羊羊的步骤 1. 导入Turtle库并设置画布 2. 绘制头部 3. 绘制眼睛 4. 绘制嘴巴 5. 绘制身体 6. 绘制四肢 7. 完成绘制 五、运行代码与结果展示 六、总结 在这个趣味盎然的技术实践中,我们将使用Python和Turtle图形…

form表单row中的col排列错位混乱

如图所示 form表单新增时排列整齐 编辑时就混乱 具体原因未知 解决方法&#xff1a;在el-row中加入样式 style"flex-wrap: wrap; display: flex" <el-row style"flex-wrap: wrap; display: flex">

OpenCV:高通滤波之索贝尔、沙尔和拉普拉斯

目录 简述 什么是高通滤波&#xff1f; 高通滤波的概念 应用场景 索贝尔算子 算子公式 实现代码 特点 沙尔算子 算子公式 实现代码 特点 拉普拉斯算子 算子公式 实现代码 特点 高通滤波器的对比与应用场景 相关阅读 OpenCV&#xff1a;图像滤波、卷积与卷积核…

error Parsing error: invalid-first-character-of-tag-name vue/no-parsing-error

标签的第一个字符不符合 HTML 或 Vue 的语法要求 [0] Module Warning (from ./node_modules/eslint-loader/index.js): [0] [0] /Users/dgq/Downloads/cursor/spid-admin/src/views/tools/fake-strategy/components/identify-list.vue [0] 87:78 error Parsing error: in…

在Unity中使用大模型进行离线语音识别

文章目录 1、Vosk下载下载vosk-untiy-asr下载模型在项目中使用语音转文字音频转文字2、whisper下载下载unity项目下载模型在unity中使用1、Vosk 下载 下载vosk-untiy-asr Github链接:https://github.com/alphacep/vosk-unity-asr 进不去Github的可以用网盘 夸克网盘链接:h…

【c语言日寄】Vs调试——新手向

【作者主页】siy2333 【专栏介绍】⌈c语言日寄⌋&#xff1a;这是一个专注于C语言刷题的专栏&#xff0c;精选题目&#xff0c;搭配详细题解、拓展算法。从基础语法到复杂算法&#xff0c;题目涉及的知识点全面覆盖&#xff0c;助力你系统提升。无论你是初学者&#xff0c;还是…

双指针+前缀和习题(一步步讲解)

前言&#xff1a;如果解决下面这几道题有些问题&#xff0c;或者即使看了我画的过程图也不理解的可以去看看我的上一篇文章&#xff0c;有可能会对你有帮助。 一、《数值元素的目标和》---来自AcWing 数组元素的目标和 给定两个升序排序的有序数组 A和 B&#xff0c;以及一个…

单调栈详解

文章目录 单调栈详解一、引言二、单调栈的基本原理1、单调栈的定义2、单调栈的维护 三、单调栈的应用场景四、使用示例1、求解下一个更大元素2、计算柱状图中的最大矩形面积 五、总结 单调栈详解 一、引言 单调栈是一种特殊的栈结构&#xff0c;它在栈的基础上增加了单调性约束…

分布式光纤应变监测是一种高精度、分布式的监测技术

一、土木工程领域 桥梁结构健康监测 主跨应变监测&#xff1a;在大跨度桥梁的主跨部分&#xff0c;如悬索桥的主缆、斜拉桥的斜拉索和主梁&#xff0c;分布式光纤应变传感器可以沿着这些关键结构部件进行铺设。通过实时监测应变情况&#xff0c;能够精确捕捉到车辆荷载、风荷…

《安富莱嵌入式周报》第349期:VSCode正式支持Matlab调试,DIY录音室级麦克风,开源流体吊坠,物联网在军工领域的应用,Unicode字符压缩解压

周报汇总地址&#xff1a;嵌入式周报 - uCOS & uCGUI & emWin & embOS & TouchGFX & ThreadX - 硬汉嵌入式论坛 - Powered by Discuz! 视频版&#xff1a; 《安富莱嵌入式周报》第349期&#xff1a;VSCode正式支持Matlab调试&#xff0c;DIY录音室级麦克风…

Pyside6(PyQT5)中的QTableView与QSqlQueryModel、QSqlTableModel的联合使用

QTableView 是QT的一个强大的表视图部件&#xff0c;可以与模型结合使用以显示和编辑数据。QSqlQueryModel、QSqlTableModel 都是用于与 SQL 数据库交互的模型,将二者与QTableView结合使用可以轻松地展示和编辑数据库的数据。 QSqlQueryModel的简单应用 import sys from PySid…

uniapp+Vue3(<script setup lang=“ts“>)模拟12306城市左右切换动画效果

效果图&#xff1a; 代码&#xff1a; <template><view class"container"><view class"left" :class"{ sliding: isSliding }" animationend"resetSliding">{{ placeA }}</view><view class"center…

VUE elTree 无子级 隐藏展开图标

这4个并没有下级节点&#xff0c;即它并不是叶子节点&#xff0c;就不需求展示前面的三角展开图标! 查阅官方文档如下描述&#xff0c;支持bool和函数回调处理&#xff0c;这里咱们选择更灵活的函数回调实现。 给el-tree结构配置一下props&#xff0c;注意&#xff01; :pr…

Ansys Motor-CAD:IPM 电机实验室 - 扭矩速度曲线

各位电动机迷们&#xff0c;大家好&#xff1a; 在本博客中&#xff0c;我讨论了如何使用 Ansys Motor-CAD 通过 LAB 模块获取扭矩速度曲线。使用每安培最大扭矩电机控制策略&#xff0c;并涵盖恒定扭矩区域和恒定功率、磁通减弱区域。分析了高转子速度如何影响功率输出。 模型…

网络(三) 协议

目录 1. IP协议; 2. 以太网协议; 3. DNS协议, ICMP协议, NAT技术. 1. IP协议: 1.1 介绍: 网际互连协议, 网络层是进行数据真正传输的一层, 进行数据从一个主机传输到另一个主机. 网络层可以将数据主机进行传送, 那么传输层保证数据可靠性, 一起就是TCP/IP协议. 路径选择: 确…