【ShardingJDBC 】【实战】----- SpringBoot3 整合 ShardingJDBC 做分库分表
文章目录Spring Boot 3 整合 Sharding-JDBC 分库分表实现Nacos配置中心配置Sharding-JDBC 配置类SysMessage 实体类mapper类服务接口类服务接口实现说明基于spring boot3 lombok 1.18.30 mybatis plus 3.5.5 nacosSpring Boot 3 整合 Sharding-JDBC 分库分表实现根据需求我们需要实现两个核心功能分库将聊天记录库和用户业务库分离 提高主业务吞吐量分表聊天记录表按用户IDdeviceId分为10个表 保证单表不超过500万数据量下面是核心配置和业务代码实现Nacos配置中心配置在Nacos中需要添加以下配置dataId可以是application-dev.yml等spring:shardingsphere:# 数据源配置datasource:# 定义所有数据源名称多个用逗号分隔names:user_db,message_db# 用户数据库配置user_db:type:com.zaxxer.hikari.HikariDataSource# 使用Hikari连接池driver-class-name:com.mysql.cj.jdbc.Driver# MySQL驱动类url:jdbc:mysql://localhost:3306/user_db?useUnicodetruecharacterEncodingutf8useSSLfalseserverTimezoneAsia/Shanghai# 数据库连接地址username:root# 数据库用户名password:root# 数据库密码# 消息数据库配置message_db:type:com.zaxxer.hikari.HikariDataSource# 使用Hikari连接池driver-class-name:com.mysql.cj.jdbc.Driver# MySQL驱动类url:jdbc:mysql://localhost:3306/message_db?useUnicodetruecharacterEncodingutf8useSSLfalseserverTimezoneAsia/Shanghai# 数据库连接地址username:root# 数据库用户名password:root# 数据库密码# 分片规则配置rules:sharding:# 表级别的分片配置tables:# 逻辑表名称sys_messagesys_message:# 实际数据节点由数据库名表名表达式组成这里表示message_db库中的sys_message_0到sys_message_9表actual-data-nodes:message_db.sys_message_${0..9}# 表分片策略table-strategy:# 标准分片策略standard:sharding-column:deviceId# 分片键使用deviceId字段进行分片sharding-algorithm-name:sys_message_inline# 引用的分片算法名称# 分片算法配置sharding-algorithms:# 与上面引用的算法名称保持一致sys_message_inline:type:INLINE# 算法类型INLINE表示使用行表达式分片算法props:# 分片算法表达式# 1. 先计算deviceId的哈希值对10取模# 2. 处理可能出现的负数情况当哈希值为负数时取模结果可能为负# 3. 确保最终结果在0-9之间对应sys_message_0到sys_message_9表algorithm-expression:sys_message_${deviceId.hashCode() % 10 10 10 ? deviceId.hashCode() % 10:deviceId.hashCode() % 10 10}Sharding-JDBC 配置类packagecom.zgb.config;importorg.apache.shardingsphere.driver.api.ShardingSphereDataSourceFactory;importorg.apache.shardingsphere.infra.config.algorithm.AlgorithmConfiguration;importorg.apache.shardingsphere.sharding.api.config.ShardingRuleConfiguration;importorg.apache.shardingsphere.sharding.api.config.rule.ShardingTableRuleConfiguration;importorg.apache.shardingsphere.sharding.api.config.strategy.sharding.StandardShardingStrategyConfiguration;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importcom.alibaba.nacos.api.config.annotation.NacosValue;importjavax.sql.DataSource;importjava.sql.SQLException;importjava.util.HashMap;importjava.util.Map;importjava.util.Properties;/** * Sharding-JDBC 配置类用于配置分库分表规则 * 从Nacos配置中心获取数据源和分片规则配置 */ConfigurationpublicclassShardingJdbcConfig{/** * 用户业务库数据源配置从Nacos获取 */NacosValue(${spring.shardingsphere.datasource.user.url})privateStringuserDbUrl;NacosValue(${spring.shardingsphere.datasource.user.username})privateStringuserDbUsername;NacosValue(${spring.shardingsphere.datasource.user.password})privateStringuserDbPassword;NacosValue(${spring.shardingsphere.datasource.user.driver-class-name})privateStringuserDbDriverClassName;/** * 聊天记录库数据源配置从Nacos获取 */NacosValue(${spring.shardingsphere.datasource.message.url})privateStringmessageDbUrl;NacosValue(${spring.shardingsphere.datasource.message.username})privateStringmessageDbUsername;NacosValue(${spring.shardingsphere.datasource.message.password})privateStringmessageDbPassword;NacosValue(${spring.shardingsphere.datasource.message.driver-class-name})privateStringmessageDbDriverClassName;/** * 配置ShardingSphere数据源 * * return 配置好的ShardingSphere数据源 * throws SQLException 数据库配置异常 */BeanpublicDataSourcedataSource()throwsSQLException{// 1. 配置数据源MapString,DataSourcedataSourcesnewHashMap(2);dataSources.put(user_db,createDataSource(userDbUrl,userDbUsername,userDbPassword,userDbDriverClassName));dataSources.put(message_db,createDataSource(messageDbUrl,messageDbUsername,messageDbPassword,messageDbDriverClassName));// 2. 配置分片规则ShardingRuleConfigurationshardingRuleConfignewShardingRuleConfiguration();// 2.1 配置消息表分表规则shardingRuleConfig.getTables().add(getSysMessageTableRuleConfiguration());// 2.2 配置分库策略按业务类型shardingRuleConfig.setDefaultDatabaseShardingStrategy(newStandardShardingStrategyConfiguration(database_type,db_inline));// 2.3 配置分片算法shardingRuleConfig.getShardingAlgorithms().put(table_inline,newAlgorithmConfiguration(INLINE,getTableShardingAlgorithmProperties()));shardingRuleConfig.getShardingAlgorithms().put(db_inline,newAlgorithmConfiguration(INLINE,getDbShardingAlgorithmProperties()));// 3. 创建并返回ShardingSphere数据源returnShardingSphereDataSourceFactory.createDataSource(dataSources,shardingRuleConfig,newProperties());}/** * 配置sys_message表的分表规则 * * return 消息表的分片规则配置 */privateShardingTableRuleConfigurationgetSysMessageTableRuleConfiguration(){ShardingTableRuleConfigurationtableRuleConfignewShardingTableRuleConfiguration(sys_message,message_db.sys_message_${0..9});// 按deviceId进行分表tableRuleConfig.setTableShardingStrategy(newStandardShardingStrategyConfiguration(deviceId,table_inline));returntableRuleConfig;}/** * 创建数据源 * * param url 数据库连接地址 * param username 数据库用户名 * param password 数据库密码 * param driverClassName 数据库驱动类名 * return 配置好的数据源 */privateDataSourcecreateDataSource(Stringurl,Stringusername,Stringpassword,StringdriverClassName){com.zaxxer.hikari.HikariConfigconfignewcom.zaxxer.hikari.HikariConfig();config.setJdbcUrl(url);config.setUsername(username);config.setPassword(password);config.setDriverClassName(driverClassName);returnnewcom.zaxxer.hikari.HikariDataSource(config);}/** * 获取表分片算法属性配置 * 按deviceId哈希后取模10分为10个表 * * return 表分片算法属性 */privatePropertiesgetTableShardingAlgorithmProperties(){PropertiespropsnewProperties();props.setProperty(algorithm-expression,sys_message_${deviceId.hashCode() % 10 10 10 ? deviceId.hashCode() % 10 : deviceId.hashCode() % 10 10});returnprops;}/** * 获取库分片算法属性配置 * 按业务类型区分用户库和消息库 * * return 库分片算法属性 */privatePropertiesgetDbShardingAlgorithmProperties(){PropertiespropsnewProperties();props.setProperty(algorithm-expression,${database_type message ? message_db : user_db});returnprops;}}SysMessage 实体类package com.zgb.entity;importcom.baomidou.mybatisplus.annotation.IdType;importcom.baomidou.mybatisplus.annotation.TableId;importcom.baomidou.mybatisplus.annotation.TableField;importcom.baomidou.mybatisplus.annotation.TableName;importlombok.Data;importjava.time.LocalDateTime;/** * 人与AI对话消息实体类 * 对应分表后的sys_message_0到sys_message_9表 */Data TableName(valuesys_message,autoResultMaptrue)publicclassSysMessage{/** * 消息ID主键自增 */TableId(typeIdType.AUTO)privateLong messageId;/** * 设备ID用于分表的关键字段 */TableField(deviceId)privateString deviceId;/** * 会话ID */TableField(sessionId)privateString sessionId;/** * 消息发送方user-用户assistant-人工智能 */privateString sender;/** * AI扮演的角色ID */privateLong roleId;/** * 消息内容 */privateString message;/** * 消息类型 */privateString messageType;/** * 语音文件路径 */privateString audioPath;/** * 状态1-有效0-删除 */privateString state;/** * 消息发送时间 */privateLocalDateTime createTime;/** * 数据库类型标识用于分库的关键字段 * 不在数据库表中仅用于分库路由 */TableField(existfalse)privateString databaseTypemessage;}mapper类package com.zgb.mapper;importcom.baomidou.mybatisplus.core.mapper.BaseMapper;importcom.zgb.entity.SysMessage;importorg.apache.ibatis.annotations.Mapper;importjava.util.List;/** * 消息表数据访问层接口 * 继承MyBatis Plus的BaseMapper提供基本CRUD操作 */Mapperpublicinterface SysMessageMapper extends BaseMapperSysMessage{/** * 根据设备ID查询消息列表 * * param deviceId 设备ID * return 该设备的消息列表 */ListSysMessageselectByDeviceId(String deviceId);/** * 根据会话ID查询消息列表 * * param sessionId 会话ID * return 该会话的消息列表 */ListSysMessageselectBySessionId(String sessionId);/** * 批量插入消息 * * param messages 消息列表 * return 插入成功的记录数 */intbatchInsert(ListSysMessagemessages);}服务接口类package com.zgb.service.impl;importcom.baomidou.mybatisplus.extension.service.impl.ServiceImpl;importcom.zgb.entity.SysMessage;importcom.zgb.mapper.SysMessageMapper;importcom.zgb.service.SysMessageService;importlombok.RequiredArgsConstructor;importorg.springframework.stereotype.Service;importorg.springframework.transaction.annotation.Transactional;importjava.util.List;/** * 消息服务实现类 * 实现消息的CRUD及相关业务操作 */Service RequiredArgsConstructorpublicclassSysMessageServiceImplextends ServiceImplSysMessageMapper,SysMessageimplements SysMessageService{privatefinalSysMessageMapper sysMessageMapper;/** * 保存消息 * * param message 消息实体必须包含deviceId用于分表路由 * return 保存成功返回true否则返回false */OverridepublicbooleansaveMessage(SysMessage message){// 设置数据库类型为message确保路由到消息库message.setDatabaseType(message);returnsave(message);}/** * 根据设备ID查询消息 * * param deviceId 设备ID用于分表路由 * return 该设备的消息列表 */OverridepublicListSysMessagegetMessagesByDeviceId(String deviceId){returnsysMessageMapper.selectByDeviceId(deviceId);}/** * 根据会话ID查询消息 * Sharding-JDBC会根据SQL中的deviceId进行路由 * * param sessionId 会话ID * return 该会话的消息列表 */OverridepublicListSysMessagegetMessagesBySessionId(String sessionId){returnsysMessageMapper.selectBySessionId(sessionId);}/** * 批量保存消息 * * param messages 消息列表每条消息必须包含deviceId用于分表路由 * return 保存成功的数量 */Override Transactional(rollbackForException.class)publicintbatchSaveMessages(ListSysMessagemessages){// 设置数据库类型为message确保路由到消息库messages.forEach(message-message.setDatabaseType(message));returnsysMessageMapper.batchInsert(messages);}}服务接口packagecom.zgb.service;importcom.baomidou.mybatisplus.extension.service.IService;importcom.zgb.entity.SysMessage;importjava.util.List;/** * 消息服务接口 * 提供消息的CRUD及相关业务操作 */publicinterfaceSysMessageServiceextendsIServiceSysMessage{/** * 保存消息 * * param message 消息实体 * return 保存成功返回true否则返回false */booleansaveMessage(SysMessagemessage);/** * 根据设备ID查询消息 * * param deviceId 设备ID * return 消息列表 */ListSysMessagegetMessagesByDeviceId(StringdeviceId);/** * 根据会话ID查询消息 * * param sessionId 会话ID * return 消息列表 */ListSysMessagegetMessagesBySessionId(StringsessionId);/** * 批量保存消息 * * param messages 消息列表 * return 保存成功的数量 */intbatchSaveMessages(ListSysMessagemessages);}实现说明分库策略通过databaseType字段区分聊天记录相关表路由到message_db用户业务表路由到user_db在消息实体类中默认设置databaseType message确保消息表操作都路由到消息库分表策略聊天记录表sys_message按deviceId的哈希值取模10分为10个表sys_message_0到sys_message_9使用INLINE算法实现分片确保相同设备的消息保存在同一个表中便于查询核心优势分片规则配置在Nacos中可动态调整无需重启服务使用MyBatis Plus简化数据库操作开发者无需关心具体操作的是哪个分表分库分表逻辑对业务代码透明降低开发复杂度以上实现满足了将聊天记录与用户业务分离存储并按用户ID水平拆分聊天记录表的需求适合高并发、大数据量的聊天场景。

相关新闻

立式与卧式影像测量仪结构区别与应用

立式与卧式影像测量仪结构区别与应用

在精密制造与质量检测领域,影像测量仪作为实现非接触式高精度尺寸测量的关键设备,其重要性日益凸显。影像测量仪也衍生出不同的机械结构形态,其中立式与卧式成为两种最主流的技术路线。这两种设备虽然核心测量原理相同,均基于光学…

2026/7/3 18:43:35 阅读更多 →
传统编曲太累?科技盘点原创音乐人信赖的5款AI编曲软件

传统编曲太累?科技盘点原创音乐人信赖的5款AI编曲软件

在音乐创作的领域里,传统编曲方式往往需要创作者投入大量的时间和精力。从构思旋律、编排和弦到制作节奏,每一个环节都可能耗费数小时甚至数天。然而,随着人工智能技术的飞速发展,AI编曲软件应运而生,为原创音乐人带来…

2026/7/6 12:38:26 阅读更多 →
2026年度硬核盘点原创音乐人必备的5款AI编曲软件

2026年度硬核盘点原创音乐人必备的5款AI编曲软件

在当今数字化音乐浪潮中,AI编曲软件正逐渐成为原创音乐人的得力助手。它们以强大的技术能力,为音乐创作带来了前所未有的便捷和创新。这些软件不仅能快速生成旋律、和声和节奏,还能根据不同的风格和需求进行个性化创作,大大缩短了…

2026/7/3 18:43:43 阅读更多 →

最新新闻

Vue开发者必看:ArcGIS Maps SDK for JavaScript Vite模板极速上手教程

Vue开发者必看:ArcGIS Maps SDK for JavaScript Vite模板极速上手教程

Vue开发者必看:ArcGIS Maps SDK for JavaScript Vite模板极速上手教程 【免费下载链接】jsapi-resources A collection of resources for developers using the ArcGIS Maps SDK for JavaScript. 项目地址: https://gitcode.com/gh_mirrors/js/jsapi-resources …

2026/7/6 19:04:44 阅读更多 →
Savant元数据处理:复杂AI应用中的数据结构设计

Savant元数据处理:复杂AI应用中的数据结构设计

Savant元数据处理:复杂AI应用中的数据结构设计 【免费下载链接】Savant Python Computer Vision & Video Analytics Framework With Batteries Included 项目地址: https://gitcode.com/gh_mirrors/sa/Savant 在计算机视觉与视频分析领域,元数…

2026/7/6 19:04:44 阅读更多 →
pydata-sphinx-theme社区贡献指南:从使用者到贡献者的转变之路

pydata-sphinx-theme社区贡献指南:从使用者到贡献者的转变之路

pydata-sphinx-theme社区贡献指南:从使用者到贡献者的转变之路 【免费下载链接】pydata-sphinx-theme A clean, three-column Sphinx theme with Bootstrap for the PyData community 项目地址: https://gitcode.com/gh_mirrors/py/pydata-sphinx-theme 想要…

2026/7/6 19:00:40 阅读更多 →
etcdadm与Kubernetes集成:构建高可用K8s集群的etcd配置

etcdadm与Kubernetes集成:构建高可用K8s集群的etcd配置

etcdadm与Kubernetes集成:构建高可用K8s集群的etcd配置 【免费下载链接】etcdadm 项目地址: https://gitcode.com/gh_mirrors/et/etcdadm etcdadm是一款专为etcd集群设计的命令行工具,它能轻松创建新集群、添加或移除成员,用户体验灵…

2026/7/6 19:00:40 阅读更多 →
终极指南:用Ice轻松打造清爽高效的macOS菜单栏

终极指南:用Ice轻松打造清爽高效的macOS菜单栏

终极指南:用Ice轻松打造清爽高效的macOS菜单栏 【免费下载链接】Ice Powerful menu bar manager for macOS 项目地址: https://gitcode.com/GitHub_Trending/ice/Ice 你是否也厌倦了macOS菜单栏上拥挤不堪的图标?各种应用的状态图标、系统工具、通…

2026/7/6 19:00:40 阅读更多 →
CTF必学:AES-ECB模式漏洞利用与密文块结构还原实战

CTF必学:AES-ECB模式漏洞利用与密文块结构还原实战

1. 项目概述:为什么AES-ECB是CTF中的“经典考点”?如果你玩过一段时间的CTF,尤其是密码学或Web安全方向的题目,那么“AES-ECB”这个组合词对你来说绝对不陌生。它就像一个老朋友,时不时就会在各种赛题里露个脸&#xf…

2026/7/6 18:58:38 阅读更多 →

日新闻

H2 与 MySQL 单元测试兼容性:5 个关键 SQL 语句差异与规避方案

H2 与 MySQL 单元测试兼容性:5 个关键 SQL 语句差异与规避方案

H2与MySQL单元测试兼容性:5个关键SQL语句差异与规避方案1. 单元测试中的数据库兼容性挑战在Java开发领域,单元测试是保证代码质量的重要环节。当应用涉及数据库操作时,测试环境的搭建往往成为开发者的痛点。H2数据库因其轻量级、内存模式和快…

2026/7/6 0:01:17 阅读更多 →
Windows任务栏终极清理指南:用RBTray一键隐藏窗口到系统托盘

Windows任务栏终极清理指南:用RBTray一键隐藏窗口到系统托盘

Windows任务栏终极清理指南:用RBTray一键隐藏窗口到系统托盘 【免费下载链接】rbtray A fork of RBTray from http://sourceforge.net/p/rbtray/code/. 项目地址: https://gitcode.com/gh_mirrors/rb/rbtray 你是否厌倦了Windows任务栏上密密麻麻的图标&…

2026/7/6 0:01:17 阅读更多 →
Visual C++ 运行时库一键安装终极指南:告别DLL缺失烦恼

Visual C++ 运行时库一键安装终极指南:告别DLL缺失烦恼

Visual C 运行时库一键安装终极指南:告别DLL缺失烦恼 【免费下载链接】vcredist AIO Repack for latest Microsoft Visual C Redistributable Runtimes 项目地址: https://gitcode.com/gh_mirrors/vc/vcredist 你是否曾经遇到过这样的情况:下载了…

2026/7/6 0:05:19 阅读更多 →

周新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/6 8:11:50 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/6 8:11:52 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/6 6:52:56 阅读更多 →

月新闻