SpringBoot集成Sharding-JDBC实现分库分表

本文已收录于专栏
《中间件合集》

目录

  • 版本介绍
  • 背景介绍
  • 拆分方式
  • 集成并测试
    • 1.引入依赖
    • 2.创建库和表
    • 3.pom文件配置
    • 4.编写测试类
      • Entity层
      • Mapper接口
      • MapperXML文件
      • 测试类
    • 5.运行结果
  • 自定义分片规则
    • 定义分片类
    • 编写pom文件
  • 总结提升

版本介绍

  SpringBoot的版本是: 2.3.12
  ShardingSphere-jdbc的版本是:5.1.2
  Mysql-Connector的版本是:8.0.19
  Druid的版本是:1.2.8

背景介绍

  分库分表是数据库设计中的一种常见策略,主要用于解决在高并发、大数据量场景下的性能瓶颈和管理问题。本文章采用Sharding-JDBC以水平分配的方式来实现分库分表。
ShardingSphere官网:https://shardingsphere.apache.org/document/5.1.2/cn/overview/
分库分表的原因:

  1. 性能提升:单一数据库在高并发情况下容易发生性能瓶颈,分库分表可以将请求分散到多个数据库或表上,降低单个数据库的压力。
  2. 容量管理:随着数据量的增长,单个数据库的存储能力可能不足。分库分表可以将数据分散到多个数据库中,以支撑更大的数据存储需求。
  3. 效率提升:在查询时,分表可以将查询范围缩小,只需要访问更少的数据,从而提高查询效率。
  4. 可维护性:分库分表可以更方便地进行数据备份、恢复和维护,提高系统的整体可维护性。
  5. 横向扩展:分库分表支持横向扩展,允许在现有架构中增加更多的数据库服务器,以适应业务增长。

拆分方式

1. 分库
  垂直分库:将不同功能模块或业务逻辑的数据存储在不同的数据库中。例如,用户数据和订单数据分别存放在不同的数据库中。
  水平分库:类似于分表,但是将同一类型的数据分散到不同的数据库中。例如,将用户数据按ID范围分散到不同的数据库。
2. 分表
  按范围分表:根据某个字段(如时间、ID等)的范围,将数据划分到不同的表中,每个表存储特定范围的数据。
  按哈希分表:对某个字段(如用户ID)进行哈希运算,根据哈希值将数据分配到不同的表中。

集成并测试

1.引入依赖

<dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.2.8</version></dependency><!-- Database Driver --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.19</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><dependency><groupId>org.apache.shardingsphere</groupId><artifactId>shardingsphere-jdbc-core-spring-boot-starter</artifactId><version>5.1.2</version></dependency>

2.创建库和表

在这里插入图片描述
  在每个数据库中都需要创建多个相同的表,例如order_info_0、order_info_2、order_info_3等等,这样在配置分片规则的时候才会根据不同的计算方式映射到不同的库和表里面。

3.pom文件配置

server:port: 8081
spring:autoconfigure: # 排除druid 否则报错exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigureshardingsphere:# 开启sql打印enabled: trueprops:# 是否显示sqlsql-show: truedatasource:#数据源名称names: sharding0,sharding1#数据源实例: 如果这里还有mastersharding0:type: com.alibaba.druid.pool.DruidDataSourcedriver-class: com.mysql.cj.jdbc.Driver#使用Druid,不能使用jdbc-url 得使用urlurl: jdbc:mysql://localhost:3307/budget-lim-dev?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghaiusername: rootpassword: 123456sharding1:type: com.alibaba.druid.pool.DruidDataSourcedriver-class: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/budget-lim-dev?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghaiusername: rootpassword: 123456#分片规则rules:sharding:#对表进行分片tables:#逻辑表名,代表的是需要分表的名称order_info:#实际节点:这里代表的是 会使用sharding数据源中 order_info表 细分为0~3 4个表actual-data-nodes: sharding$->{0..1}.order_info_$->{0..1}#库策略database-strategy:standard:#根据num来进行分库sharding-column: numsharding-algorithm-name: alg_round-robin#表策略table-strategy:#标准表策略standard:#分表的列sharding-column: id#分片算法名称: 来源于下面的sharding-algorithmssharding-algorithm-name: alg_randomkey-generate-strategy: # 主键生成策略column: id  # 主键列key-generator-name: snowflake  # 策略算法名称(推荐使用雪花算法)#主键生成规则,SNOWFLAKE 雪花算法key-generators:snowflake:type: SNOWFLAKE#分片算法sharding-algorithms:alg_hash_mod:#类型:hash取余  类似于获取一个列的数type: HASH_MOD#分片的数量,因为是2个表,所以是2props:sharding-count: 2mybatis:#映射文件 配置之后,mybatis会去扫描该路径下的xml文件,才会与Mapper对应起来mapper-locations: classpath:mapper/*.xml#别名类(实体类)所在包type-aliases-package: com.wzil.simplesharding.entityconfiguration:#驼峰转换map-underscore-to-camel-case: true

4.编写测试类

Entity层

/*** @Author: wzil* @DATE: 2024年7月24日* @Description:**/
@Data
public class OrderInfo {private Long id;private String name;private Integer num;private Date createTime;
}

Mapper接口

/*** @Author: wzil* @DATE: 2024年7月24日15:26:30* @Description: 创建mapper接口,**/@Mapper
public interface OrderInfoMapper {List<OrderInfo> list();void save(OrderInfo orderInfo);void deleteById(@Param("id") Long id);void updateNameById(@Param("id") Long id, @Param("name") String name);OrderInfo getById(@Param("id") Long id);List<OrderInfo> limitOrder();List<OrderInfo> limitOrderWithOffset();}

MapperXML文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--namespace:命名空间,用来映射对应的mapper
相当于将mapper和mapper.xml连接起来,这一步很重要-->
<mapper namespace="com.wzil.simplesharding.mapper.OrderInfoMapper"><insert id="save">insert into order_info(`name`,num,create_time) values(#{name},#{num},#{createTime})</insert><update id="updateNameById">update order_info set name=#{name}where id=#{id}</update><delete id="deleteById">delete from order_info where id=#{id}</delete><select id="list" resultType="com.wzil.simplesharding.entity.OrderInfo">select * from order_info</select><select id="getById" resultType="com.wzil.simplesharding.entity.OrderInfo">select * from order_infowhere id=#{id}</select><select id="limitOrder" resultType="com.wzil.simplesharding.entity.OrderInfo">select * from order_infoorder by num desclimit 10</select><select id="limitOrderWithOffset" resultType="com.wzil.simplesharding.entity.OrderInfo">select * from order_infoorder by num desclimit 2,10</select>
</mapper>

测试类

@Slf4j
@SpringBootTest
class SimpleShardingApplicationTests {@Autowiredprivate OrderInfoMapper orderInfoMapper;@Testvoid add() {for (int i = 0; i < 100; i++) {OrderInfo orderInfo = new OrderInfo();orderInfo.setName("wzil"+i);orderInfo.setCreateTime(new Date());orderInfo.setNum(i);orderInfoMapper.save(orderInfo);}}@Testvoid delete() {Long id=1022869460031111169L;orderInfoMapper.deleteById(id);}@Testvoid update() {Long id=1022869460031111169L;String name="hello";orderInfoMapper.updateNameById(id,name);}@Testvoid list() {List<OrderInfo> list = orderInfoMapper.list();System.out.println(list);}@Testvoid getById() {Long id=1022869460031111169L;OrderInfo info=orderInfoMapper.getById(id);System.out.println(info);}
}

5.运行结果

在这里插入图片描述
  此实例运行的是更新的语句,可以看到是对sharding1数据库中的order_info_0进行更新操作的。

自定义分片规则

定义分片类

package com.wzil.simplesharding.config;import org.apache.shardingsphere.sharding.api.sharding.standard.PreciseShardingValue;
import org.apache.shardingsphere.sharding.api.sharding.standard.RangeShardingValue;
import org.apache.shardingsphere.sharding.api.sharding.standard.StandardShardingAlgorithm;import java.util.Collection;
import java.util.Properties;/*** @BelongsProject: simple_sharding* @BelongsPackage: com.wzil.simplesharding.config* @Author: Wuzilong* @Description: 轮询分片算法* @CreateTime: 2024-07-24 14:21* @Version: 1.0*/public class RoundRobinShardingAlgorithm implements StandardShardingAlgorithm<String> {int currentIndex=0;@Overridepublic String doSharding(Collection<String> collection, PreciseShardingValue<String> preciseShardingValue) {// 计算当前的索引位置currentIndex = (currentIndex + 1) % collection.size();// 根据当前索引返回数据源名称return (String) collection.toArray()[currentIndex];}@Overridepublic Collection<String> doSharding(Collection<String> collection, RangeShardingValue<String> rangeShardingValue) {return null;}@Overridepublic Properties getProps() {return null;}@Overridepublic void init(Properties properties) {}
}

  编写一个分片规则的类去实现StandardShardingAlgorithm接口,去重写doSharding方法。doSharding(Collection collection, PreciseShardingValue preciseShardingValue)这个方法是确定值的分片规则。 doSharding(Collection collection, RangeShardingValue rangeShardingValue)这个方法是范围值的分片规则。根据业务的需求来重写不同的方法。

编写pom文件

        #分片算法sharding-algorithms:alg_round-robin:#指定了算法的类型type: CLASS_BASEDprops:#标准的分片策略strategy: standard#算法类的全限定名algorithmClassName: com.wzil.simplesharding.config.RoundRobinShardingAlgorithm

  编写完之后就可以在上面配置的分库或者分表的规则去指定我们自己定义的alg_round-robin这个类型了。
在这里插入图片描述

总结提升

  分库分表是一种有效的数据库设计策略,能够应对高并发和大数据量的挑战。尽管其带来了复杂性和维护成本,但在许多实际应用中,以提升性能和可扩展性为目标的分库分表依然是一个广泛采用的解决方案。在实施之前,需要深入分析业务需求和技术架构,合理设计分库分表策略,以便最大化其效益。

🎯 此文章对你有用的话记得留言+点赞+收藏哦🎯

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

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

相关文章

IDEA Maven使用HTTP代理,解决Could not transfer artifact org.xxx问题

文章目录 一、前言二、遇到问题三、分析问题四、HTTP代理五、重新编译验证 一、前言 遇到这个问题&#xff0c;有两种解决办法 IDEA Maven使用HTTP代理&#xff0c;解决Could not transfer artifact org.xxx问题IDEA Maven使用国内镜像&#xff0c;解决Could not transfer arti…

C语言分支语句之if的一些用法

目录 引言C语言结构 1. if 语句1.1 if1.2 else 2. 分支中包含多条语句3. 多重选择 else if4. 嵌套if5. 悬空else / else与if配对问题 引言 C语言作为一种非常常用的编程语言&#xff0c;具有灵活强大的循环和分支结构。循环结构允许我们重复执行一段代码&#xff0c;而分支结构…

【网络爬虫技术】(1·绪论)

&#x1f308; 个人主页&#xff1a;十二月的猫-CSDN博客 &#x1f525; 系列专栏&#xff1a; &#x1f3c0;网络爬虫开发技术入门_十二月的猫的博客-CSDN博客 &#x1f4aa;&#x1f3fb; 十二月的寒冬阻挡不了春天的脚步&#xff0c;十二点的黑夜遮蔽不住黎明的曙光 目录 …

本地部署Graphhopper路径规划服务(graphhopper.sh启动版)

文章目录 文章参考源码获取一、配置Java环境变量二、配置Maven环境变量三、构建graphhopper步骤1. 下载数据2. 配置graphhopper配置文件config-example.yml3. 在项目中启动命令行执行./graphhopper.sh build3.1|、遇到的问题3.1.1、pom.xml中front-maven-plugin-无法下载npm6.1…

跨境电商独立站:Shopify/Wordpress/店匠选哪个?

在面对不断增加的平台运营压力时&#xff0c;不少跨境电商的商家逐渐将注意力转向建立自己的独立站。据《中国跨境出口电商发展报告&#xff08;2022&#xff09;》所示&#xff0c;中国拥有的独立站数量在2022年已接近20万个&#xff0c;这表明独立站已成为卖家拓展海外市场的…

昇思25天学习打卡营第11天|xiaoyushao

今天分享ResNet50迁移学习。 在实际应用场景中&#xff0c;由于训练数据集不足&#xff0c;所以很少有人会从头开始训练整个网络。普遍的做法是&#xff0c;在一个非常大的基础数据集上训练得到一个预训练模型&#xff0c;然后使用该模型来初始化网络的权重参数或作为固定特征提…

苦学Opencv的第十一天:图像的形态学操作

Python OpenCV从入门到精通学习日记&#xff1a;图像的形态学操作 前言 图像形态学是图像处理中的一个重要分支&#xff0c;主要关注图像中物体的形状和结构。通过形态学操作&#xff0c;我们可以对图像进行有效的分析和处理&#xff0c;例如图像的腐蚀与膨胀、开运算与闭运算…

大模型学习笔记十四:Agent模型微调

文章目录 一、大模型需要Agent技术的原因二、Prompt Engineering可以实现Agent吗&#xff1f;&#xff08;1&#xff09;ReAct原理展示和代码&#xff08;2&#xff09;ModelScope&#xff08;3&#xff09;AutoGPT&#xff08;4&#xff09;ToolLLaMA 三、既然AutoGPT可以满足…

利用OSMnx求路网最短路径并可视化(二)

书接上回&#xff0c;为了增加多路径的可视化效果和坐标匹配最近点来实现最短路可视化&#xff0c;我们使用图形化工具matplotlib结合OSMnx的绘图功能来展示整个路网图&#xff0c;并特别高亮显示计算出的最短路径。 多起终点最短路路径并计算距离和时间 完整代码#运行环境 P…

C++——QT:保姆级教程,从下载到安装到用QT写出第一个程序

登录官网&#xff0c;在官网选择合适的qt版本进行下载 这里选择5.12.9版本 点击exe文件下载&#xff0c;因为服务器在国外&#xff0c;国内不支持&#xff0c;所以可以从我的网盘下载 链接: https://pan.baidu.com/s/1XMILFS1uHTenH3mH_VlPLw 提取码: 1567 --来自百度网盘超级…

Linux--网络基础

目录 1.计算机网络背景 2. 初识协议 2.1概念 2.2 协议分层 2.3OSI 七层模型 2.4TCP/IP 五层(或四层)模型 3.再识协议 3.1为什么要有 TCP/IP 协议&#xff1f; 3.2什么是 TCP/IP 协议&#xff1f; 3.3TCP/IP 协议与操作系统的关系(宏观上&#xff0c; 怎么实现的) 3.…

一键解锁:科研服务器性能匹配秘籍,选择性能精准匹配科研任务和计算需求的服务器

一键解锁&#xff1a;科研服务器性能匹配秘籍 HPC科研工作站服务器集群细分领域迷途小书童 专注于HPC科研服务器细分领域kyfwq001 &#x1f3af;在当今科技飞速发展的时代&#xff0c;科研工作对计算资源的需求日益增长&#x1f61c;。选择性能精准匹配科研任务和计算需求的服…

HarmonyOS和OpenHarmony区别联系

前言 相信我们在刚开始接触鸿蒙开发的时候经常看到HarmonyOS和OpenHarmony频繁的出现在文章和文档之中&#xff0c;那么这两个名词分别是什么意思&#xff0c;他们之间又有什么联系呢&#xff1f;本文将通过现有的文章和网站内容并与Google的AOSP和Android做对比&#xff0c;带…

助力樱桃智能自动化采摘,基于嵌入式端超轻量级模型LeYOLO全系列【n/s/m/l】参数模型开发构建果园种植采摘场景下樱桃成熟度智能检测识别系统

随着科技的飞速发展&#xff0c;人工智能&#xff08;AI&#xff09;技术已经渗透到我们生活的方方面面&#xff0c;从智能家居到自动驾驶&#xff0c;再到医疗健康&#xff0c;其影响力无处不在。然而&#xff0c;当我们把目光转向中国的农业领域时&#xff0c;一个令人惊讶的…

python-NLP:2词性标注与命名实体识别

文章目录 词性标注命名实体识别时间命名实体&#xff08;规则方法&#xff09;CRF 命名实体识别方法 词性标注 词性是词汇基本的语法属性&#xff0c;通常也称为词类。词性标注是在给定句子中判定每个词的语法范畴&#xff0c;确定其词性并加以标注的过程。例如&#xff0c;表示…

【React】详解“最新”和“最热”切换与排序

文章目录 一、基本概念和初始化二、切换与排序功能的实现1. 函数定义和参数2. 设置活动 Tab3. 定义新列表变量4. 根据排序类型处理列表4.1 按时间降序排序4.2 按点赞数降序排序 5. 更新评论列表 三、渲染导航 Tab 和评论列表1. map 方法2. key 属性3. className 动态赋值4. onC…

模式Hash和history

vuerouter有两种路由模式Hash和history。区别&#xff1a;Hash为默认模式&#xff0c;url中包含一个#符号的哈希部分。优势&#xff1a;兼容性好&#xff0c;不需要后端服务器的特殊配置。缺点&#xff1a;不够美观&#xff0c;搜索引擎优化较差。History模式使用的浏览器的His…

小程序多排数据横向滚动实现

如何实现多排数据滚动效果 swiper 外部容器 swiper-item 每一页的数据 因为现在有多排数据,现在在swiper-item 中需要循环一个数组 初版 <template><view><view class"container"><view class"swiper-box"><swiper class&qu…

《Utilizing Ensemble Learning for Detecting Multi-Modal Fake News》

系列论文研读目录 文章目录 系列论文研读目录论文题目含义ABSTRACTINDEX TERMSI. INTRODUCTIONII. RELATED WORKA. FAKE NEWS CLASSIFICATION APPROACHES FOR SINGLE-MODALITY 单模态虚假新闻分类方法1) SINGLE-MODALITY BASED CLASSIFICATION APPROACHES USING TEXTUAL FEATUR…

家政项目小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;家政人员管理&#xff0c;家政服务管理&#xff0c;咨询信息管理&#xff0c;咨询服务管理&#xff0c;家政预约管理&#xff0c;留言板管理&#xff0c;系统管理 微信端账号功能…