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

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

目录

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

3.编写测试类

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);}
}

4.运行结果

在这里插入图片描述
  此实例运行的是更新的语句,可以看到是对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.xdnf.cn/news/1488007.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

电子期刊制作攻略:从零开始,轻松入门

​随着互联网的快速发展&#xff0c;电子期刊已经逐渐成为人们获取信息和娱乐的重要途径。越来越多的人开始关注并投身于电子期刊的制作行业。那么&#xff0c;如何从零开始&#xff0c;轻松入门电子期刊制作呢&#xff1f; 1.首先点击FLBOOK在线制作制作电子杂志平台 2.点击开…

【odoo17】后端py方法触发右上角提示组件

概要 在前面文章中&#xff0c;有介绍过前端触发的通知服务。 【odoo】右上角的提示&#xff08;通知服务&#xff09; 此文章则介绍后端触发方法。 内容 直接上代码&#xff1a;但是前提一定是按钮触发&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; def bu…

无法解析插件 org.apache.maven.plugins:maven-war-plugin:3.2.3(已解决)

文章目录 1、问题出现的背景2、解决方法 1、问题出现的背景 最开始我想把springboot项目转为javaweb项目&#xff0c;然后我点击下面这个插件 就转为javaweb项目了&#xff0c;但是我后悔了&#xff0c;想要还原成springboot项目&#xff0c;点开项目结构关于web的都移除了&am…

HarmonyOS Next 省市区级联(三级联动)筛选框

效果图 完整代码 实例对象 export class ProvinceBean {id?: stringpid?: stringisSelect?: booleandeep?: objectextName?: stringchildren?: ProvinceBean[] }级联代码 import { MMKV } from tencent/mmkv/src/main/ets/utils/MMKV import { ProvinceBean } from ..…

【Git】merge合并分支

两个分支未修改同一个文件的同一处位置: Git自动合并 两个分支修改了同一个文件的同一处位置:产生冲突 例&#xff1a; 在master分支修改了main同时&#xff0c;feat分支也修改了相同的文件 合并的时候就会产生冲突 解决方法: Step1- 手工修改冲突文件&#xff0c;合并冲突内容…

【数据结构】单链表的增删改查

介绍 链表是有序的列表&#xff0c;但是它在内存中是如下存储的&#xff1a; ①链表以节点的方式进行存储&#xff0c;是链式存储的 ②每个节点包含 data 域、next 域&#xff1a;指向下一节点 ③链表的各个节点不一定是连续存放的 ④链表分为有头节点的链表和没有头节点的链表…

比肩 GPT-4o 的 Llama 3.1 本地部署快速体验的方法

比肩 GPT-4o 的 Llama 3.1 本地部署快速体验的方法 flyfish Llama 3.1模型简介 Llama 3.1是一系列大型语言模型&#xff0c;包含以下几种规模&#xff1a; 8B 参数&#xff1a;模型中有80亿个参数 70B 参数&#xff1a;模型中有700亿个参数 405B 参数&#xff1a;模型中有4…

深入理解MySQL锁机制与性能优化:详解记录锁、间隙锁、临键锁及慢SQL查询分析

1. 事务隔离和锁机制详解 记录锁 第一种情况,当我们对于唯一性的索引(包括唯一索引和主键索引)使用等值查询,精准匹配到一条记录的时候,这个时候使用的就是记录锁。 比如 where id = 1 4 7 10。 间隙锁 第二种情况,当我们查询的记录不存在,无论是用等值查询还是范围…

【vue教程】四. Vue 计算属性和侦听器

目录 本章涵盖知识点回顾计算属性&#xff08;Computed&#xff09;创建计算属性计算属性的多样性计算属性的数组过滤计算属性的复杂表达式 计算属性 vs 方法计算属性的实例演示 侦听器&#xff08;Watchers&#xff09;创建侦听器侦听器的高级用法侦听器的深度观察侦听器的立即…

无线遥控控制直流电机和无刷电机开关

一 目的 此文章记录了arduino与陶晶驰串口屏实现联动&#xff0c;点击屏幕双态开关远程控制arduino2560板载的直流电机和无刷电机开关。为手搓乒乓球发球机做准备。 二 接线 2.1串口屏接线 串口屏与Arduino UNO接线如下&#xff1a; ———————————————— RX …

pdf2image:将PDF文档转化为图像的Python魔法

标题&#xff1a;探索pdf2image&#xff1a;将PDF文档转化为图 像的Python魔法 背景 在数字时代&#xff0c;我们经常需要处理各种格式的文档&#xff0c;尤其是PDF文件。PDF以其跨平台的可读性和稳定性而广受欢迎。然而&#xff0c;有时我们需要将PDF文件转换成图像格式&am…

C++ - char*、const char*、char[]、string

const char* const char* 用来定义字符串常量。 char[ ] char型的字符数组是一种定长的数组&#xff0c;存储指定长度的字符序列&#xff0c;数组中的每个元素都是一个char类型的变量&#xff0c;如&#xff1a; char arr[] {h, a, l, l, o, \0}; char c arr[0]; // 访问…

CentOS怎么关闭自动锁屏?

禁止自动锁屏 有时候几分钟不用Centos&#xff0c;系统就自动锁屏了&#xff0c;这是一种安全措施&#xff0c;防止别人趁你不在时使用你的系统。但对于大部分人而言&#xff0c;这是没有必要的&#xff0c;尤其是Centos虚拟机&#xff0c;里面没啥重要的东西&#xff0c;每次…

光伏发电管理软件:光伏企业的核心驱动力

光伏产业面对日益增长的装机容量、复杂多变的运维需求以及激烈的市场竞争&#xff0c;光伏企业如何高效管理、优化运营、提升效益&#xff0c;成为了行业关注的焦点。在此背景下&#xff0c;鹧鸪云光伏发电管理软件应运而生&#xff0c;并逐渐成为光伏企业的核心驱动力。 一、提…

Transformer合集

资料 位置编码&#xff1a;https://zhuanlan.zhihu.com/p/454482273 自注意力&#xff1a;https://zhuanlan.zhihu.com/p/455399791 LN&#xff1a;https://zhuanlan.zhihu.com/p/456863215 ResNet&#xff1a;https://zhuanlan.zhihu.com/p/459065530 Subword Tokenizati…

效率翻倍的秘密:探索AI工具的新世界

大家好&#xff0c;我是你们的效率小助手米兔&#xff01;你是否曾在加班熬夜中挣扎&#xff0c;对着电脑屏幕发呆&#xff0c;感觉工作效率低到怀疑人生&#xff1f;别急&#xff0c;今天我要给你们安利几款超给力的AI工具&#xff0c;让你的工作变得轻松又愉快&#xff01; …

c++笔记4

目录 深度优先搜索DFS DFS的复杂度 DFS与递归 递归与暴力枚举 递归树 DFS与栈 DFS的搜索剪枝 搜索剪枝与优化 可行性剪枝 最优化剪枝 减少等效的分支 优化搜索顺序 搜索的记忆化 搜索的复杂度 大多时候&#xff0c;搜索的复杂度都是指数级的。各种剪枝方案&#…

2024世界技能大赛某省选拔赛“网络安全项目”B模块--操作系统取证解析

2024世界技能大赛某省选拔赛“网络安全项目”B模块--操作系统取证解析 任务一、操作系统取证解析:总结:任务一、操作系统取证解析: A 集团某电脑系统被恶意份子攻击并控制,怀疑其执行了破坏操作,窃取了集团内部的敏感信息,现请分析 A 集团提供的系统镜像和内存镜像,找到…

WIX Toolset 3.11 对本地化的支持方案

1.准备主题文件和本地化文件 WIX Toolset种主题文件为xml文件&#xff0c;负责配置控件的布局&#xff0c; 本地化文件为wxl文件&#xff0c;负责配置待加载的字符串&#xff0c;主题文件根据ID加载需要显示的文字内容。考虑到英文和中文字符长度大小不一&#xff0c;所以这里…

与Bug较量:Codigger之软件项目体检Software Project HealthCheck来帮忙

在软件工程师的世界里&#xff0c;与 Java 小程序中的 Bug 作战是一场永不停歇的战役。每一个隐藏在代码深处的 Bug 都像是一个狡猾的敌人&#xff0c;时刻准备着给我们的项目带来麻烦。 最近&#xff0c;我就陷入了这样一场与 Java 小程序 Bug 的激烈较量中。这个小程序原本应…