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

SpringBoot+Mybatis-plus+shardingsphere实现分库分表

SpringBoot+Mybatis-plus+shardingsphere实现分库分表

文章目录

  • SpringBoot+Mybatis-plus+shardingsphere实现分库分表
    • 介绍
    • 引入依赖
    • yaml配置
    • DDL准备
      • 数据库ds0
      • 数据库ds1
    • entity
    • cotroller
    • service
    • Mapper
    • 启动类
    • 测试
      • 添加
      • 修改
      • 查询
      • 删除
    • 总结

介绍

实现亿级数据量分库分表的项目是一个挑战性很高的任务,下面是一个基于Spring Boot的简单实现方案:

  1. 数据库选择:使用MySQL数据库,因为MySQL在分库分表方面有较成熟的解决方案。

  2. 分库分表策略:可以采用水平分库分表的策略,根据一定的规则将数据分散存储在不同的数据库和表中,例如可以根据用户ID、订单ID等进行分片。

  3. 数据分片策略:可以采用基于雪花算法的分布式ID生成器来生成全局唯一的ID,确保数据在不同数据库和表中的唯一性。

  4. 数据同步:考虑到数据分散存储在不同的数据库和表中,需要实现数据同步机制来保证数据的一致性,可以使用Canal等开源工具来实现MySQL数据的实时同步。

  5. 连接池优化:在处理大量数据时,连接池的配置尤为重要,可以使用Druid等高性能的连接池来提升数据库连接的效率。

  6. 缓存机制:考虑使用Redis等缓存工具来缓存热点数据,减轻数据库的压力,提升系统性能。

  7. 分布式事务:在分库分表的场景下,涉及到跨库事务,可以考虑使用分布式事务框架,如Seata等来保证事务的一致性。

  8. 监控与调优:实时监控数据库的性能指标,及时调整分片策略和数据库配置,保证系统的稳定性和性能。

引入依赖

<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.28</version></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.4.3</version></dependency><!--分库分表--><!-- Sharding-JDBC --><dependency><groupId>org.apache.shardingsphere</groupId><artifactId>shardingsphere-jdbc-core-spring-boot-starter</artifactId><version>5.2.0</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies>

yaml配置

server:port: 10086spring:shardingsphere:# 数据源配置datasource:# 数据源名称,多数据源以逗号分隔names: db0,db1db0:type: com.zaxxer.hikari.HikariDataSourcedriver-class-name: com.mysql.cj.jdbc.Driverjdbc-url: jdbc:mysql://127.0.0.1:3306/ds0?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=trueusername: rootpassword: rootdb1:type: com.zaxxer.hikari.HikariDataSourcedriver-class-name: com.mysql.cj.jdbc.Driverjdbc-url: jdbc:mysql://127.0.0.1:3306/ds1?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=trueusername: rootpassword: root# 分片规则配置rules:sharding:# 分片算法配置sharding-algorithms:database-inline:# 分片算法类型type: INLINEprops:# 分片算法的行表达式(算法自行定义,此处为方便演示效果)algorithm-expression: db$->{age % 2}table-inline:# 分片算法类型type: INLINEprops:# 分片算法的行表达式algorithm-expression: user_$->{age % 3}tables:# 逻辑表名称user:# 行表达式标识符可以使用 ${...} 或 $->{...},但前者与 Spring 本身的属性文件占位符冲突,因此在 Spring 环境中使用行表达式标识符建议使用 $->{...}actual-data-nodes: db${0..1}.user_${0..2}# 分库策略database-strategy:standard:# 分片列名称sharding-column: age# 分片算法名称sharding-algorithm-name: database-inline# 分表策略table-strategy:standard:# 分片列名称sharding-column: age# 分片算法名称sharding-algorithm-name: table-inline# 属性配置props:# 展示修改以后的sql语句sql-show: true

DDL准备

数据库ds0

-- ds0.user_0 definitionCREATE TABLE `user_0` (`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',`name` varchar(32) NOT NULL COMMENT '姓名',`age` int NOT NULL COMMENT '年龄',PRIMARY KEY (`id`)
) ENGINE=InnoDB COMMENT='用户表';
-- ds0.user_1 definitionCREATE TABLE `user_1` (`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',`name` varchar(32) NOT NULL COMMENT '姓名',`age` int NOT NULL COMMENT '年龄',PRIMARY KEY (`id`)
) ENGINE=InnoDB COMMENT='用户表';
-- ds0.user_2 definitionCREATE TABLE `user_2` (`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',`name` varchar(32) NOT NULL COMMENT '姓名',`age` int NOT NULL COMMENT '年龄',PRIMARY KEY (`id`)
) ENGINE=InnoDB COMMENT='用户表';

数据库ds1

-- ds1.user_0 definitionCREATE TABLE `user_0` (`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',`name` varchar(32) NOT NULL COMMENT '姓名',`age` int NOT NULL COMMENT '年龄',PRIMARY KEY (`id`)
) ENGINE=InnoDB COMMENT='用户表';
-- ds1.user_1 definitionCREATE TABLE `user_1` (`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',`name` varchar(32) NOT NULL COMMENT '姓名',`age` int NOT NULL COMMENT '年龄',PRIMARY KEY (`id`)
) ENGINE=InnoDB COMMENT='用户表';
-- ds1.user_2 definitionCREATE TABLE `user_2` (`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',`name` varchar(32) NOT NULL COMMENT '姓名',`age` int NOT NULL COMMENT '年龄',PRIMARY KEY (`id`)
) ENGINE=InnoDB COMMENT='用户表';

entity

package com.kang.sharding.entity;import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;@Data
@TableName("user")  
public class User {@TableId(value = "id",type = IdType.AUTO)private Long id;private String name;private Integer age;// getter, setter, toString...  
}

cotroller

package com.kang.sharding.controller;import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.kang.sharding.entity.User;
import com.kang.sharding.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;import java.util.List;@RestController  
@RequestMapping("/user")  
public class UserController {  @Autowired  private UserService userService;@PostMapping ("add")public boolean createUser(@RequestBody User user) {return userService.save(user);  }@PostMapping ("update")public boolean updateByAge(@RequestBody User user){LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>();// 分片数据不允许更新,否则会报错updateWrapper.eq(User::getAge,user.getAge()).set(User::getName,user.getName());return userService.update(updateWrapper);}@GetMapping ("delete")public boolean deleteUserByAge(@RequestParam("age") Integer age) {LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();queryWrapper.eq(User::getAge,age);return userService.remove(queryWrapper);}@GetMapping("/{age}")public List<User> getUserByAge(@PathVariable Integer age) {LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();queryWrapper.eq(User::getAge,age);return userService.list(queryWrapper);}  // 其他方法...  
}

service

package com.kang.sharding.service;import com.kang.sharding.entity.User;
import com.kang.sharding.mapper.UserMapper;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;  @Service  
public class UserService extends ServiceImpl<UserMapper, User> {
}

Mapper

package com.kang.sharding.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.kang.sharding.entity.User;
import org.apache.ibatis.annotations.Mapper;@Mapper
public interface UserMapper extends BaseMapper<User> {
}

启动类

package com.kang.sharding;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class ShardingJdbcProjectApplication {public static void main(String[] args) {SpringApplication.run(ShardingJdbcProjectApplication.class, args);}}

测试

添加

在这里插入图片描述
在这里插入图片描述

修改

在这里插入图片描述
在这里插入图片描述

查询

在这里插入图片描述

在这里插入图片描述

删除

在这里插入图片描述

在这里插入图片描述

总结

这只是个简单的入门示例,后续深入研究

相关文章:

SpringBoot+Mybatis-plus+shardingsphere实现分库分表

SpringBootMybatis-plusshardingsphere实现分库分表 文章目录 SpringBootMybatis-plusshardingsphere实现分库分表介绍引入依赖yaml配置DDL准备数据库ds0数据库ds1 entitycotrollerserviceMapper启动类测试添加修改查询删除 总结 介绍 实现亿级数据量分库分表的项目是一个挑战…...

FPGA DDR3简介及时序

一&#xff0c;DDR3基础知识 1、DDR3全称第三代双倍速率同步动态随机存储器。 特点:①掉电无法保存数据&#xff0c;需要周期性的刷新。 ②时钟上升沿和下降沿都会传输数据。 ③突发传输,突发长度Burst Length一般为8 2、DDR3的存储: bank、行地址和列地址 数据怎么存入到D…...

java网络编程 02 socket

01.socket定义 02.TCP编程 import java.io.IOException; import java.io.OutputStream; import java.net.InetAddress; import java.net.Socket;public class clientSocket {public static void main(String[] args) throws IOException {Socket socket new Socket(Ine…...

【Web安全】SQL各类注入与绕过

【Web安全】SQL各类注入与绕过 【Web安全靶场】sqli-labs-master 1-20 BASIC-Injection 【Web安全靶场】sqli-labs-master 21-37 Advanced-Injection 【Web安全靶场】sqli-labs-master 38-53 Stacked-Injections 【Web安全靶场】sqli-labs-master 54-65 Challenges 与62关二…...

C++ 设计模式

文章目录 类图泛化实现关联聚合组合依赖总结 类内部的三种权限&#xff08;公有、保护、私有&#xff09;类的三种继承方式描述与图总结 面向对象七大原则单一职责原则&#xff08;Single Responsibility Principle&#xff09;里氏替换原则&#xff08;Liskov Substitution Pr…...

安卓使用ExoPlayer出现膨胀类异常

1.导包 implementation com.google.android.exoplayer:exoplayer-core:2.15.1implementation com.google.android.exoplayer:exoplayer-ui:2.15.1 2.在Androidifest.xml加入权限&#xff0c;我这里加了网络与读写权限 <uses-permission android:name"android.permissio…...

C++之析构函数

在 C 中&#xff0c;析构函数&#xff08;Destructor&#xff09;是一个特殊的成员函数&#xff0c;用于在对象生命周期结束时执行清理工作和资源释放。析构函数的名称与类名相同&#xff0c;前面加上波浪号&#xff08;~&#xff09;&#xff0c;不接受任何参数&#xff0c;也…...

108. 将有序数组转换为二叉搜索树【简单】

108. 将有序数组转换为二叉搜索树【简单】 题目描述&#xff1a; 给你一个整数数组 nums &#xff0c;其中元素已经按 升序 排列&#xff0c;请你将其转换为一棵 高度平衡 二叉搜索树。 高度平衡 二叉树是一棵满足「每个节点的左右两个子树的高度差的绝对值不超过 1 」的二叉…...

vue3中watch和watchEffect的区别!!!

vue3中watch和watchEffect的区别&#xff01;&#xff01;&#xff01; 在 Vue 3 中&#xff0c;watch 和 watchEffect 都是监听器&#xff0c;但在写法和使用上有所区别。让我们来详细了解一下它们之间的不同&#xff1a; watch: watch 具有一定的惰性&#xff08;lazy&#…...

【JavaEE初阶 -- 计算机核心工作机制】

这里写目录标题 1.冯诺依曼体系2.CPU是怎么构成的3.指令表4.CPU执行代码的方式5.CPU小结&#xff1a;6.编程语言和操作系统7. 进程/任务&#xff08;Process/Task&#xff09;8.进程在系统中是如何管理的9. CPU分配 -- 进程调度10.内存分配 -- 内存管理11.进程间通信 1.冯诺依曼…...

springcloud:3.6测试信号量隔离

服务提供者【test-provider8001】 Openfeign远程调用服务提供者搭建 文章地址http://t.csdnimg.cn/06iz8 相关接口 测试远程调用&#xff1a;http://localhost:8001/payment/index 服务消费者【test-consumer-resilience4j8004】 Openfeign远程调用消费者搭建 文章地址http://t…...

AI化未来:智能科技的新纪元

AI化未来&#xff1a;智能科技的新纪元 我们正处在一个前所未有的科技革新时期&#xff0c;人工智能&#xff08;AI&#xff09;的发展正日益渗透到我们生活的方方面面&#xff0c;预示着AI化未来的到来。这是一场前所未有的科技革命&#xff0c;其深度和广度超越了历史上的任…...

Unity 整体界面淡入淡出效果

在Unity中&#xff0c;如果我们要实现控制多个组件同时淡出&#xff0c;同时淡入的效果&#xff0c;可以使用DOTween插件实现。 如图&#xff0c;一个页面中带有背景&#xff0c;一张图片&#xff0c;一个文本&#xff0c;一个滑动条。 要实现以上界面的整体淡入淡出&#xff…...

反序列化逃逸 [安洵杯 2019]easy_serialize_php1

打开题目 题目源码&#xff1a; <?php$function $_GET[f];function filter($img){$filter_arr array(php,flag,php5,php4,fl1g);$filter /.implode(|,$filter_arr)./i;return preg_replace($filter,,$img); }if($_SESSION){unset($_SESSION); }$_SESSION["user&qu…...

JavaScript中的包装类型详解

JavaScript中的包装类型详解 在 JavaScript 中&#xff0c;我们有基本类型和对象类型两种数据类型。基本类型包括 String&#xff0c;Number&#xff0c;Boolean&#xff0c;null&#xff0c;undefined 和 Symbol。然而&#xff0c;当我们需要在这些基本类型上调用方法时&…...

如何向各大媒体网站投稿 海外媒体发稿平台有哪些

在数字化时代&#xff0c;各大媒体网站是企业推广和个人展示的重要平台。通过在媒体网站上发布文章&#xff0c;可以有效地扩大影响力和提升知名度。但是&#xff0c;如何投稿到各大媒体网站呢&#xff1f;以下是一些常用的方法和步骤。 1. 研究目标媒体 在投稿之前&#xff0…...

基于SpringBoot的论坛系统(附项目源码+论文)

摘要 如今的时代&#xff0c;是有史以来最好的时代&#xff0c;随着计算机的发展到现在的移动终端的发展&#xff0c;国内目前信息技术已经在世界上遥遥领先&#xff0c;让人们感觉到处于信息大爆炸的社会。信息时代的信息处理肯定不能用之前的手工处理这样的解决方法&#xf…...

堆以及堆的实现

文章目录 堆的概念堆的实现HeapPushHeapPop HeapTop HeapSize HeapEmpty堆的应用 堆的概念 堆是一颗完全二叉树每个结点的值都小于子结点的值&#xff0c;这颗二叉树为小根堆每个结点的值都大于子结点的值&#xff0c;这颗二叉树为大根堆堆的定义如下&#xff1a;n个元素的序列…...

使用RabbitMQ实现延时消息自动取消的简单案例

一、流程图 二、导包 <!--消息队列 AMQP依赖&#xff0c;包含RabbitMQ--> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId> </dependency> 三、配置文件 #消息队列 …...

Docker部署(ruoyi案例接上篇Docker之部署前后端分离项目)实施必会!!!!

文章目录 Docker部署前端 Docker部署前端 接上篇博主已经部署好后端Docker部署后端&#xff0c;现在来讲解怎么部署前端 MySQL和redis是不依赖其他任何一个东西的&#xff0c; ruoyi-admin是因为你启动项目的时候是必须连接数据库的 现在去单独启动它 docker start ruoyi-a…...

电脑中已经有多个模组压缩文件,如何通过小火星露谷管理器批量安装

如果已经下载了很多的星露谷模组压缩文件&#xff08;zip包&#xff09;&#xff0c;可以通过【添加模组】功能&#xff0c;将模组批量解压到Mods文件夹中。 名词解释 为了避免这篇文章的内容看不懂&#xff0c;先解释两个名词。 直装型模组&#xff1a;直接解压到Mods就能生…...

[Linux]如何理解kernel、shell、bash

文章目录 概念总览kernelshell&bash 概念总览 内核(kernel) &#xff0c;外壳(shell) &#xff0c;bash kernel kernel是指操作系统中的核心部分&#xff0c;用户一般是不能直接使用kernel的。它主要负责管理硬件资源和提供系统服务&#xff0c;如内存管理、进程管理、文件…...

C++:Vector的使用

一、vector的介绍 vector的文档介绍 1. vector是表示可变大小数组的序列容器。 2. 就像数组一样&#xff0c;vector也采用的连续存储空间来存储元素。也就是意味着可以采用下标对vector的元素进行访问&#xff0c;和数组一样高效。但是又不像数组&#xff0c;它的大小是可以…...

Redis之事务(详细解析)

请直接看原文:不能回滚的Redis事务还能用吗 - 知乎 (zhihu.com) ------------------------------------------------------------------------------------------------------------------------------ 1、Redis事务的概念&#xff1a; Redis 事务的本质是一组命令的集合。…...

Java项目:39 springboot007大学生租房平台的设计与实现

作者主页&#xff1a;源码空间codegym 简介&#xff1a;Java领域优质创作者、Java项目、学习资料、技术互助 文中获取源码 项目介绍 系统有管理员、房东和用户 【主要功能】 1、后台&#xff1a;房源管理、信息审批管理、订单信息管理、房东管理、用户管理 2、前台&#xff1…...

安卓内存信息查看

目录 前言一、Android查看内存相关信息的方法1.1 通过 adb shell 获取内存信息1.2 通过编程方式获取内存信息1.3 adb shell 获取应用程序内存使用情况1.4 free指令 二、总结 前言 一、Android查看内存相关信息的方法 1.1 通过 adb shell 获取内存信息 C:\Users\henry.xue>…...

Positional Encoding 位置编码

Positional Encoding 位置编码 flyfish Transformer模型没有使用循环神经网络&#xff0c;无法从序列中学习到位置信息&#xff0c;并且它是并行结构&#xff0c;不是按位置来处理序列的&#xff0c;所以为输入序列加入了位置编码&#xff0c;将每个词的位置加入到了词向量中…...

MySql、Navicat 软件安装 + Navicat简单操作(建数据库,表)

一、MySql、Navicat 软件安装 及正常使用 MySql下载&#xff0b;安装&#xff1a; 检查安装情况&#xff1a; 配置环境变量&#xff1a; 搞定了&#xff01;&#xff01;&#xff01; 可以登陆试哈哈哈 连接navicat 开始创建数据库 二、 商品种类表 - commoditytype int …...

逆向案例五、爬取b站评论,表单MD5加密

1.便捷写爬虫网站&#xff1a; Convert curl commands to code 使用流程&#xff1a;又点击想要抓的包&#xff0c;复制URL&#xff08;base&#xff09;格式复制 在上面链接中粘贴即可 2.找到含有评论的包&#xff08;即main?oid)&#xff1a;观察表单发现两处参数在变化&…...

010-原型链

原型链 1、概念2、原理3、new 操作符原理4、应用 1、概念 原型链&#xff1a;javascript的继承机制&#xff0c;是指获取JavaScript对象的属性会顺着其_proto_的指向寻找&#xff0c;直至找到Object.prototype上。 2、原理 &#x1f4a1; Tips&#xff1a;构造函数 Fn&#…...