使用ShardingJDBC实现分库分表

一、测试环境

  1. JDK:1.8
  2. SpringBoot:2.7.17
  3. MySQL驱动:5.1.49
  4. MyBatis:2.3.1
  5. shardingJDBC:5.1.0

二、核心依赖

<!-- mysql 驱动 -->
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.49</version>
</dependency><!-- mybatis 依赖 -->
<dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.3.1</version>
</dependency><!-- sharding-jdbc依赖 -->
<dependency><groupId>org.apache.shardingsphere</groupId><artifactId>shardingsphere-jdbc-core-spring-boot-starter</artifactId><version>5.1.0</version>
</dependency>

三、测试分库分表思路

在本地配置了两个数据库 testshardingdb1 和 testshardingdb2,然后每个库中有两个表user_1 和 user_2,使用分库分表工具 shardingJDBC 实现分库分表。

四、配置分库分表策略(关键)

具体配置文件如下:

# 控制台输出彩色日志
spring.output.ansi.enabled: ALWAYS# 定义数据源。这里定义了两个数据源,分别为m1和m2
spring.shardingsphere.datasource.names=m1,m2# 初始化m1数据源。包括初始化连接url、用户名、密码、驱动类名、数据源类型
spring.shardingsphere.datasource.m1.url=jdbc:mysql://127.0.0.1:3306/testshardingdb1?characterEncoding=utf8&useSSL=false
spring.shardingsphere.datasource.m1.username=root
spring.shardingsphere.datasource.m1.password=123456
spring.shardingsphere.datasource.m1.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.m1.type=com.zaxxer.hikari.HikariDataSource# 同样的配置项也适用于数据源m2,只是将前缀中的m1改为m2,将数据库名替换。
spring.shardingsphere.datasource.m2.url=jdbc:mysql://127.0.0.1:3306/testshardingdb2?characterEncoding=utf8&useSSL=false
spring.shardingsphere.datasource.m2.username=root
spring.shardingsphere.datasource.m2.password=123456
spring.shardingsphere.datasource.m2.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.m2.type=com.zaxxer.hikari.HikariDataSource# 数据分片信息存储在内存中,适用于轻量级的应用或者开发、测试环境。
spring.shardingsphere.mode.type=Memory# 定义了逻辑表user在不同数据库中的实际数据节点,$->{1..2}表示数据源的数量,$->{1..2}表示数据库的数量。
spring.shardingsphere.rules.sharding.tables.user.actualDataNodes=m$->{1..2}.user_$->{1..2}
# 定义了数据库分片策略的分片键,这里使用了user表的sex列作为分片键。
spring.shardingsphere.rules.sharding.tables.user.databaseStrategy.standard.shardingColumn=sex
# 定义了数据库分片策略使用的分片算法,这里使用了名为database-inline的内联分片算法。
spring.shardingsphere.rules.sharding.tables.user.databaseStrategy.standard.shardingAlgorithmName=database-inline
# 定义了表分片策略的分片键,这里使用了user表的id列作为分片键。
spring.shardingsphere.rules.sharding.tables.user.tableStrategy.standard.shardingColumn=id
# 定义了表分片策略使用的分片算法,这里使用了名为table-inline的内联分片算法。
spring.shardingsphere.rules.sharding.tables.user.tableStrategy.standard.shardingAlgorithmName=table-inline# 定义了名为database-inline的内联分片算法的类型
spring.shardingsphere.rules.sharding.shardingAlgorithms.database-inline.type=INLINE
# 定义了database-inline分片算法的具体算法表达式,这里根据sex列的值进行分片,将奇数的数据放在m1数据源中,偶数的数据放在m2数据源中。
spring.shardingsphere.rules.sharding.shardingAlgorithms.database-inline.props.algorithm-expression=m$->{sex % 2 + 1}
# 定义了名为table-inline的内联分片算法的类型。
spring.shardingsphere.rules.sharding.shardingAlgorithms.table-inline.type=INLINE
# 定义了table-inline分片算法的具体算法表达式,这里根据id列的值进行分片,为了打乱这里采用模3。
spring.shardingsphere.rules.sharding.shardingAlgorithms.table-inline.props.algorithm-expression=user_$->{(id % 3 == 0) ? id % 3 + 1 : id % 3}# 定义了user表主键生成策略的列名,这里使用id列作为主键。
spring.shardingsphere.rules.sharding.tables.user.key-generate-strategy.column=id
# 定义了默认的主键生成策略,这里使用了snowflake算法。
spring.shardingsphere.sharding.default-key-generate-strategy.xxx=snowflake
# 定义了名为snowflake的主键生成策略的类型,这里使用了Snowflake算法。
spring.shardingsphere.rules.sharding.key-generators.snowflake.type=SNOWFLAKE# 打开sql输出日志
spring.shardingsphere.props.sql-show=true# 指定 xxxMapper.xml的扫描路径
mybatis.mapper-locations: classpath:mapper/**/*.xml

上述配置实现了基于sex和id两个字段对数据进行分片,通过配置不同的分片算法和分片键,将数据分散存储在不同的数据库和表中,简单实现了数据的水平拆分负载均衡

五、编写数据库操作语句

@Data
public class User {private Long id; // 雪花id-64位private String name; // 姓名private int sex; // 性别
}
@Mapper
public interface ShardingDao {// 往库表插入数据int insertUser(User user);// 查询所有库表数据List<User> selectUser();}

注意:mapper.xml中SQL语句中的表名是上面配置的逻辑表名:user

<?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">
<mapper namespace="com.example.demo.dao.ShardingDao"><insert id="insertUser" parameterType="com.example.demo.model.User">insert into user(name, sex) values (#{name}, #{sex})</insert><select id="selectUser" resultType="com.example.demo.model.User">select * from user</select>
</mapper>

六、分库分表测试

1、插入100条数据

@SpringBootTest
public class ShardingJDBCTest {@Autowiredprivate ShardingDao shardingDao;@Autowiredprivate DataSource dataSource;// 插入100条数据@Testpublic void testInsertShardingJDBC() {User user = new User();for(int i=0; i<100; i++) {user.setName("小明" + i);user.setSex(i);if(shardingDao.insertUser(user) == 1) {System.out.println("插入成功!");} else {System.out.println("插入失败!");}}}// 查询所有数据@Testpublic void testSelectShardingJDBC() {List<User> users = shardingDao.selectUser();if (users == null) {System.out.println("查询失败!结果为null");} else {for (User user:users) {System.out.println(user);}}}
}

因为上面我们开启了shardingJDBC的打印日志,控制台可以看到逻辑SQL和实际SQL:

查看插入结果:

2、查询所有数据

@SpringBootTest
public class ShardingJDBCTest {@Autowiredprivate ShardingDao shardingDao;@Autowiredprivate DataSource dataSource;// 查询所有数据@Testpublic void testSelectShardingJDBC() {List<User> users = shardingDao.selectUser();if (users == null) {System.out.println("查询失败!结果为null");} else {for (User user:users) {System.out.println(user);}}}
}

查询结果(部分):

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

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

相关文章

网站架构演变、LNP+Mariadb数据库分离、Web服务器集群、Keepalived高可用

目录 day02 深入理解程序的数据存储 验证 配置NFS服务器 配置代理服务器 配置名称解析 day02 深入理解程序的数据存储 程序将文字数据保存到数据库中程序将非文字数据&#xff08;如图片、视频、压缩包等&#xff09;保存到相应的文件目录中 验证 发一篇文章&#xf…

Manifest merger failed with multiple errors, see logs

问题 Manifest merger failed with multiple errors, see logs详细问题 笔者进行Android 项目开发&#xff0c;修改AndroidManifest.xml代码后&#xff0c;控制台报错 AndroidManifest.xml报错核心代码 <manifest><uses-permission android:name"android.perm…

StringBuilder/StringBuffer类(Java)

StringBuilder/StringBuffer类 当对字符串进行修改的时候&#xff0c;使用 StringBuffer / StringBuilder 类更方便。和 String 类不同的是&#xff0c;StringBuffer 和 StringBuilder 类的对象能够被多次的修改&#xff0c;并且不产生新的未使用对象。方法类似 public class…

力扣:300. 最长递增子序列

动态规划: 1. 先定义dp数组来表示在下标为i时最长递增子序列&#xff0c;先初始化一下每个下标的值为dp【i】1。同时我们要判断在下标i之前的最长的递增子序列为多少&#xff0c;在判断当前的下标i是否满足递增的条件满足的话就进行dp【i】的重新赋值。之后要更新接受的最长递…

【C语言】长篇详解,字符系列篇1-----“混杂”的各种字符类型字符转换和strlen的模拟实现【图文详解】

欢迎来CILMY23的博客喔&#xff0c;本期系列为【C语言】长篇详解&#xff0c;字符系列篇1-----“混杂”的各种字符函数……&#xff0c;图文讲解各种字符函数&#xff0c;带大家更深刻理解C语言中各种字符函数的应用&#xff0c;感谢观看&#xff0c;支持的可以给个赞哇。 前言…

内存块与内存池

&#xff08;1&#xff09;在运行过程中&#xff0c;MemoryPool内存池可能会有多个用来满足内存申请请求的内存块&#xff0c;这些内存块是从进程堆中开辟的一个较大的连续内存区域&#xff0c;它由一个MemoryBlock结构体和多个可供分配的内存单元组成&#xff0c;所有内存块组…

Java学习笔记------static

static 创建Javabean类 public class student {private int age;private String name;private String gender;public student() {}public student(int age, String name, String gender) {this.age age;this.name name;this.gender gender;}/*** 获取* return age*/public…

MySQL的索引类型

目录 1. 主键索引 (PRIMARY KEY) 2. 唯一索引 (UNIQUE) 3. 普通索引 (INDEX) 4. 全文索引 (FULLTEXT) 5. 空间索引 (SPATIAL) 6. 组合索引 (COMPOSITE INDEX) 7. 前缀索引 (PREFIX INDEX) 8. 覆盖索引 (COVERING INDEX) 1. 主键索引 (PRIMARY KEY) 描述&#xff1a;表…

使用Python编写脚本-根据端口号杀掉进程

我的GitHub&#xff1a;Powerveil - GitHub 我的Gitee&#xff1a;Powercs12 - Gitee 皮卡丘每天学Java 从前段开始遇到一个问题&#xff0c;服务在启动的时候总是端口被占用&#xff0c;发现还是Java程序&#xff0c;但是当时并没有启动Java程序&#xff0c;电脑出问题了。 一…

请解释Java中的字节码是什么,它与源代码和机器码有什么关系?

请解释Java中的字节码是什么&#xff0c;它与源代码和机器码有什么关系&#xff1f; 在Java编程语言中&#xff0c;源代码&#xff08;即.java文件&#xff09;经过编译器编译后会生成字节码&#xff08;即.class文件&#xff09;&#xff0c;字节码是一种中间代码&#xff0c…

AndroidFrameWork切换帧率

文章目录 参考资料 简述 一. SurfaceFlinger接受帧率变化1.1 SurfaceFlinger.setDesiredActiveConfig1.2 SurfaceFlinger.repaintEverythingForHWC1.3 Scheduler.resyncToHardwareVsync1.3.1 Scheduler.setVsyncPeriod1.3.2 VSyncReactor.setPeriod1.3.3 VSyncReactor.startPe…

【Linux】Framebuffer 应用

# 前置知识 LCD 操作原理 在 Linux 系统中通过 Framebuffer 驱动程序来控制 LCD。 Frame 是帧的意思&#xff0c; buffer 是缓冲的意思&#xff0c;这意味着 Framebuffer 就是一块内存&#xff0c;里面保存着一帧图像。 Framebuffer 中保存着一帧图像的每一个像素颜色值&…

Tomcat要点总结

一、Tomcat 服务中部署 WEB 应用 1.什么是Web应用 &#xff08;1&#xff09; WEB 应用是多个 web 资源的集合。简单的说&#xff0c;可以把 web 应用理解为硬盘上的一个目录&#xff0c; 这个目录用于管理多个 web 资源。 &#xff08;2&#xff09;Web 应用通常也称之为…

每日一个shell脚本之一键部署Agent提高工作效率!

每日一个shell脚本之一键部署Agent提高工作效率&#xff01; 源码参上 #!/usr/bin/bash # **************************************# CSDN: M乔木 # qq邮箱: 2776617348qq.com # 解释器: 这是一个shell脚本 # **…

七、ActiveMQ的传输协议

ActiveMQ的传输协议 一、是什么二、协议1.TCP(默认)2.NIO3.AMQP4.STOMP5.SSL6.MQTT7 WS 三、NIO配置案例1.修改activemq.xml2.重启3.生产者/消费者4.性能提升4.1 配置4.2 生产者/消费者 一、是什么 官网地址&#xff1a;http://activemq.apache.org/configuring-version-5-tra…

C语言——oj刷题——找单身狗2

题目名称&#xff1a; 寻找只出现一次的两个数字 题目内容&#xff1a; 在一个数组中&#xff0c;只有两个数字出现了一次&#xff0c;其他所有数字都出现了两次。本篇博客将介绍如何编写一个函数来找出这两个只出现一次的数字。 解题思路&#xff1a; 要解决这个问题&#…

WordPress Nginx 报错 502 Bad Gateway

之前租了一台服务器&#xff0c;部署了Nginx&#xff0c;WordPress。 最近机器重启了一次&#xff0c;访问WordPress就发现报错502 Bad Gateway。 然后查询/home/wwwlogs/nginx_error.log发现如下错误 2024/02/17 21:07:57 [crit] 5551#0: *19 connect() to unix:/tmp/php-cgi…

C++单例模式的实现

单例模式就是在整个程序运行期都只有一个实例。在代码实现方面&#xff0c;我们要限制new出多于一个对象这种情况的发生。而不是仅仅依靠无保障的约定。 目前大多数的编程语言的做法都是私有化构造函数&#xff0c;对外提供一个获取实例的接口。这样做的目的使实例的创建不能在…

Mysql知识点汇总

Mysql知识点汇总 1. Mysql基本场景的简单语句。2. Mysql的增删改查&#xff0c;统计表中的成绩最好的两个同学的名字&#xff0c;年级等。3&#xff1a;请使用多种方法查询每个学生的每门课分数>80的学生姓名4、order by&#xff0c;group by&#xff0c;子查询4.1、having和…

抖店需要怎么做?具体流程来了,建议收藏!

我是电商珠珠 很多人在创业的时候&#xff0c;都热衷于选择线上&#xff0c;特别是对于做店没有任何经验的新手来说&#xff0c;不敢轻易将自己十几年来的血汗钱做实体店而付之东流。 抖店作为一个发展了三年的电商平台来说&#xff0c;其市场份额达到了35%&#xff0c;热度一…