使用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 {

    @Autowired
    private ShardingDao shardingDao;
    @Autowired
    private DataSource dataSource;

	// 插入100条数据
    @Test
    public 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("插入失败!");
            }
        }
    }
    
	// 查询所有数据
    @Test
    public 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 {

    @Autowired
    private ShardingDao shardingDao;
    @Autowired
    private DataSource dataSource;

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

查询结果(部分):

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Django学习笔记教程全解析:初步学习Django模型,初识API,以及Django的后台管理系统(Django全解析,保姆级教程)

把时间用在思考上是最能节省时间的事情。——[美]卡曾斯 导言 写在前面 本文部分内容引用的是Django官方文档&#xff0c;对官方文档进行了解读和理解&#xff0c;对官方文档的部分注释内容进行了翻译&#xff0c;以方便大家的阅读和理解。 概述 在上一篇文章里&#xff0…

【Python】高级数据类型

&#x1f6a9; WRITE IN FRONT &#x1f6a9; &#x1f50e; 介绍&#xff1a;"謓泽"正在路上朝着"攻城狮"方向"前进四" &#x1f50e;&#x1f3c5; 荣誉&#xff1a;2021|2022年度博客之星物联网与嵌入式开发TOP5|TOP4、2021|2222年获评…

8.JS中的== 操作符的强制类型转换规则

对于 来说&#xff0c;如果对比双方的类型不一样&#xff0c;就会进行类型转换。假如对比 x 和 y 是否相同&#xff0c;就会进行如下判断流程&#xff1a; 首先会判断两者类型是否相同&#xff0c;类型相同的话就比较两者的大小&#xff1b;类型不相同的话&#xff0c;就会进…

Compose低级别API动画指南

Google官方为Compose提供的动画API与原生View体系的动画API相差甚远&#xff0c;目前总共分为四类&#xff1a;高级别动画API、低级别动画API、自定义动画、手势和动画&#xff08;其他&#xff09;&#xff0c;下图是官方提供的流程指示图&#xff0c;以供根据不同使用场景来选…

PMDG 737

在Simbrief中生成计划后下载两个文件 放到A:\Xbox\Community\pmdg-aircraft-738\Config\Flightplans中

深度学习疆界:探索基本原理与算法,揭秘应用力量,展望未来发展与智能交互的新纪元

目录 什么是深度学习 深度学习的基本原理和算法 深度学习的应用实例 深度学习的挑战和未来发展方向 挑战 未来发展方向 深度学习与机器学习的关系 深度学习与人类的智能交互 什么是深度学习 深度学习是一种基于神经网络的机器学习方法&#xff0c;旨在模仿人类大脑分析…

LabVIEW虚拟测试与分析仪

LabVIEW虚拟测试与分析仪 在现代工程技术领域&#xff0c;虚拟仪器的开发和应用已成为一种趋势。利用LabVIEW软件平台开发的虚拟测试与分析仪器进行展开&#xff0c;实现工程测试和分析中的实际需求。通过结合LabVIEW的强大功能和灵活性&#xff0c;成功实现了一套高效、精确的…

各指针含义区分

一、char *a P109: (1)(变量)指针变量&#xff1a;指针变量&#xff0c;即指针的定义&#xff1a;用来存放指针的变量。指向的是变量&#xff0c;且可以改变其指向的地址。P104 char *a (2)(变量)指针常量&#xff1a;指针常量&#xff0c;指向的是变量首字节的地址&#xff…

算法基础——单调栈,单调队列

目录 1.单调栈 例题&#xff1a;【模板】单调栈 例题:求和 2.单调队列 例题&#xff1a;滑动窗口 1.单调栈 例题&#xff1a;【模板】单调栈 可以想象出一个柱状图&#xff0c;值越大&#xff0c;这个柱子越高 以此题的样例为例&#xff1a; 第一个数为7&#xff0c;想…

【Java程序员面试专栏 分布式中间件】ElasticSearch 核心面试指引

关于ElasticSearch 部分的核心知识进行一网打尽,包括ElasticSearch 的基本概念,基本架构,工作流程,存储机制等,通过一篇文章串联面试重点,并且帮助加强日常基础知识的理解,全局思维导图如下所示 基础概念 从数据分类入手,考察全文索引的基本概念 现实世界中数据有哪…

yolov5配置教程

yolov5 yolov5 notepad notepad 直接下一步就可以 Git Git 取消勾选 修改默认编辑器为npp 其他都直接下一步 python3.8.1 python3.8.1 主要勾选添加环境变量 其他下一步即可 Miniconda Miniconda 其他下一步 然后添加系统环境变量 Pycharm Pycharm 把这个界面所…

MPLAB V8.92 printf

Compile error “A heap is required, but has not been specified” Set printf function #if 0 //for UART1 int fputc(int ch, FILE *f) { IFS1bits.U2TXIF 0; // if (runConfig.printOn 1) { // usart_data_transmit(USART0, (uint8_t)ch); U2TXREG ch; // while (RESE…

linux(阿里云)安装pytorch

目录 环境 安装步骤 1 检查python3和pip3是否已经安装 2 安装pytorch 3 安装完毕&#xff0c;检查pytorch版本 环境 阿里云 ubuntu 22.04 UEFI版 64位 安装步骤 1 检查python3和pip3是否已经安装 输入下面两条指令&#xff1a; python3 --version pip --version 检…

Nvm安装(windows版)

1、nvm 是什么 &#xff08;1&#xff09;nvm(Node.js version manager) 是一个命令行应用&#xff0c;可以协助您快速地 更新、安装、使用、卸载 本机的全局 node.js 版本。 &#xff08;2&#xff09;有时候&#xff0c;我们可能同时在进行多个项目开发&#xff0c;而多个项…

书生·浦语大模型第六课作业

面向GPU的环境安装 conda create --name opencompass --clone/root/share/conda_envs/internlm-base source activate opencompass git clone https://github.com/open-compass/opencompass cd opencompass pip install -e . 数据准备 # 解压评测数据集到 data/ 处 cp /shar…

神经网络 | CNN 与 RNN——深度学习主力军

Hi&#xff0c;大家好&#xff0c;我是半亩花海。本文主要将卷积神经网络&#xff08;CNN&#xff09;和循环神经网络&#xff08;RNN&#xff09;这两个深度学习主力军进行对比。我们知道&#xff0c;从应用方面上来看&#xff0c;CNN 用于图像识别较多&#xff0c;而 RNN 用于…

c++阶梯之类与对象(下)

前文&#xff1a; c阶梯之类与对象&#xff08;上&#xff09;-CSDN博客 c阶梯之类与对象&#xff08;中&#xff09;-CSDN博客 c阶梯之类与对象&#xff08;中&#xff09;&#xff1c; 续集 &#xff1e;-CSDN博客 1. 再谈构造函数 1.1 构造函数体赋值 在创建对象时&a…

Go教程-什么是编程?

什么是编程&#xff0c;这是个有趣的话题。 编程是什么 编程&#xff0c;字面意思即编写程序&#xff0c;即通过既定的关键字&#xff0c;来描述你的想法&#xff0c;并让计算机的各个部件按照你的想法来做事。 这里计算机的各个部件通常来说&#xff0c;指的是CPU和IO设备。…

对进程与线程的理解

目录 1、进程/任务&#xff08;Process/Task&#xff09; 2、进程控制块抽象(PCB Process Control Block) 2.1、PCB重要属性 2.2、PCB中支持进程调度的一些属性 3、 内存分配 —— 内存管理&#xff08;Memory Manage&#xff09; 4、线程&#xff08;Thread&#xff09;…

linux系统配置zabbix监控agent端

目录 客户端配置 启动服务 浏览器工具设置 创建主机群组 创建主机 创建监控项 ​编辑 ​编辑 创建触发器 查看监控 客户端配置 rpm -Uvh https://repo.zabbix.com/zabbix/5.0/rhel/7/x86_64/zabbix-release-5.0-1.el7.noarch.rpm # yum clean allyum install -y zab…