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

Sharding-jdbc基本使用步骤以及执行原理剖析

一、基本使用步骤

1、需求说明

使用sharding-jdbc完成对订单表的水平分表,通过快速入门的开发,了解sharding-jdbc使用方法

人工创建两张表,t_order_1和t_order_2,这两张表是订单表拆分后的表,通过sharding-jdbc向订单表插入数据,按照一定的分片规则,主键为偶数的进入t_order_1,另一部分数据进入t_order_2,通过sharding-jdbc查询数据,根据SQL语句的内容从t_order_1或t_order_2查询数据。

2、环境搭建

创建订单数据库order_db

CREATE DATABASE order_db CHARACTER SET 'utf8' COLLATE 'utf8_general_ci'; 1

在order_db中创建t_order_1、t_order_2表

DROP TABLE IF EXISTS t_order_1;CREATE TABLE t_order_1 (`order_id` BIGINT ( 20 ) NOT NULL COMMENT '订单id',`price` DECIMAL ( 10, 2 ) NOT NULL COMMENT '订单价格',`user_id` BIGINT ( 20 ) NOT NULL COMMENT '下单用户id',`status` VARCHAR ( 50 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '订单状态',PRIMARY KEY ( `order_id` ) USING BTREE 
) ENGINE = INNODB CHARACTER 
SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;DROP TABLE IF EXISTS t_order_2;
CREATE TABLE t_order_2 (`order_id` BIGINT ( 20 ) NOT NULL COMMENT '订单id',`price` DECIMAL ( 10, 2 ) NOT NULL COMMENT '订单价格',`user_id` BIGINT ( 20 ) NOT NULL COMMENT '下单用户id',`status` VARCHAR ( 50 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '订单状态',PRIMARY KEY ( `order_id` ) USING BTREE 
) ENGINE = INNODB CHARACTER 
SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

创建工程,引入坐标

    <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.1.0.RELEASE</version><relativePath/><!-- lookup parent from repository --></parent><dependencies><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.0</version><scope>provided</scope></dependency><!-- MySQL Connector/J for database connectivity --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.47</version></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.1.0</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.1.16</version></dependency><dependency><groupId>org.apache.shardingsphere</groupId><artifactId>sharding-jdbc-spring-boot-starter</artifactId><version>4.0.0-RC1</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><version>2.1.0.RELEASE</version><scope>test</scope></dependency></dependencies>

3、配置文件

在application.properties中进行如下配置:(尤其关注sharding-jdbc的配置,我已经将每条配置都解释的很详细了)

# 端口号
server.port=56000
# 应用名称
spring.application.name=sharding_quick
# 表示spring中发现的bean会覆盖之前相同名称的bean
spring.main.allow-bean-definition-overriding=true
# 该配置项,将数据库中带有下划线的字段名称映射成驼峰命名
mybatis.configuration.map-underscore-to-camel-case=true# 以下配置为sharding-jdbc分片规则配置# 1.定义数据源
#定义数据源名称
spring.shardingsphere.datasource.names=m1
#数据源连接数据库
spring.shardingsphere.datasource.m1.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.m1.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.m1.url=jdbc:mysql://localhost:3306/order_db?useUnicode=true
spring.shardingsphere.datasource.m1.username=root
spring.shardingsphere.datasource.m1.password=123456# 2.指定订单表的数据分布情况,配置数据节点 下面的't_order'是逻辑表,这个名字可以自己起一个   m1.t_order_$->{1..2}表示利用行表达式来实现动态表
spring.shardingsphere.sharding.tables.t_order.actual-data-nodes=m1.t_order_$->{1..2}# 3.指定t_order表中的主键生成策略#表示告诉sharding-jdbc数据库表中的那一个字段进行主键生成
spring.shardingsphere.sharding.tables.t_order.key-generator.column=order_id
#指定具体的主键生成策略  -> 雪花算法
spring.shardingsphere.sharding.tables.t_order.key-generator.type=SNOWFLAKE# 4.指定t_order表的分片策略(分片策略=分片键+分片算法):主键为偶数路由到t_order_1中,否则插入到t_order_2中#告诉分片键是哪一个字段
spring.shardingsphere.sharding.tables.t_order.tableStrategy.inline.shardingColumn=order_id
#确定采取什么样的分片算法
spring.shardingsphere.sharding.tables.t_order.tableStrategy.inline.algorithmExpression=t_order_$->{order_id % 2 + 1}# 5.指定,打开sharding-jdbc提供的sql输出日志配置
spring.shardingsphere.props.sql.show=true# 日志配置
logging.level.root=info
logging.level.org.springframework=info
logging.level.com.lcc=debug
logging.level.druid.sql=debug

4、完成新增订单功能

创建订单实体

import lombok.Data;import java.math.BigDecimal;@Data
public class Order {private Long orderId;private BigDecimal price;private Long userId;private String status;}

创建mapper接口

import com.lcc.domain.Order;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;import java.util.List;
import java.util.Map;@Mapper
public interface OrderMapper {/*** 这里t_order就是sharding-jdbc中的逻辑表*/@Insert("insert into t_order(price,user_id,status) values(#{price},#{userId},#{status})")public int insertOrder(Order order);
}

在测试类中进行测试 

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;@RunWith(SpringRunner.class)
@SpringBootTest
public class ShardingQuickApplicationTests {@Autowiredprivate OrderMapper orderMapper;@Testpublic void insertTest(){for (int i = 0; i < 10; i++) {Order order = new Order();order.setStatus("success_"+i);order.setUserId(1L);order.setPrice(new BigDecimal((i+1)*5));int result = orderMapper.insertOrder(order);System.out.println(result);}}
}

我们查看数据库发现,已经根据我们的分片策略进行不同orderId的落盘

5、完成查询订单功能

在mapper中新增selectListByOrderIds方法

@Mapper
public interface OrderMapper {/*** 这里t_order就是sharding-jdbc中的逻辑表*/@Insert("insert into t_order(price,user_id,status) values(#{price},#{userId},#{status})")public int insertOrder(Order order);@Select("<script>" +"select " +"* " +"from t_order t " +"where t.order_id in " +"<foreach collection='orderIds' item='id' open='(' separator=',' close=')'>" +"#{id}" +"</foreach>" +"</script>")public List<Map> selectListByOrderIds(@Param("orderIds") List<Long> orderIds);
}

在测试类中新增selectTest方法

@RunWith(SpringRunner.class)
@SpringBootTest
public class ShardingQuickApplicationTests {@Autowiredprivate OrderMapper orderMapper;@Testpublic void insertTest(){for (int i = 0; i < 10; i++) {Order order = new Order();order.setStatus("success_"+i);order.setUserId(1L);order.setPrice(new BigDecimal((i+1)*5));int result = orderMapper.insertOrder(order);System.out.println(result);}}@Testpublic void selectTest(){List<Long> orderIds = new ArrayList<>();orderIds.add(1074443883426873344L);orderIds.add(1074443883489787905L);List<Map> maps = orderMapper.selectListByOrderIds(orderIds);for (Map map : maps) {System.out.println(map);}}
}

二、sharding-jdbc执行原理剖析

我们先来看一张官网上给出的大致执行流程图

我们再调整一下,SQL路由应该在SQL改写的前面,如下图

1、SQL解析

首先,使用内置的 SQL 解析器对原始 SQL 进行解析,识别出查询中的表名、条件、分组、排序等信息。这一步骤确保了后续操作能够正确地针对分片后的数据库和表进行。

2、SQL路由

根据分片策略和解析后的 SQL 信息,确定需要访问的具体分片。对于涉及多表关联查询的情况,还会检查是否为绑定表(Binding Table),以优化查询路径。

3、SQL改写

基于路由结果,对原始 SQL 进行必要的改写,例如替换表名为实际的分片表名,调整 LIMIT 子句等,以适应分片后的环境。

4、SQL执行

在完成 SQL 改写后,Sharding-JDBC 会为每个目标分片生成独立的执行计划。这意味着每个分片上的查询都会被视为单独的 SQL 操作,并行执行。

5、结果归并

由于同一个查询可能涉及到多个分片的数据,因此 Sharding-JDBC 需要负责将从各个分片获取的结果集合并成最终的结果返回给应用程序。这个过程包括:

  • 数据去重:对于某些聚合查询或 DISTINCT 关键字的使用,需要去除重复记录。

  • 排序和分页:如果原始查询包含 ORDER BY 或 LIMIT 等子句,则需要对合并后的结果重新排序或截取指定数量的记录。

相关文章:

Sharding-jdbc基本使用步骤以及执行原理剖析

一、基本使用步骤 1、需求说明 使用sharding-jdbc完成对订单表的水平分表&#xff0c;通过快速入门的开发&#xff0c;了解sharding-jdbc使用方法 人工创建两张表&#xff0c;t_order_1和t_order_2&#xff0c;这两张表是订单表拆分后的表&#xff0c;通过sharding-jdbc向订…...

mysql重置root密码(适用于5.7和8.0)

今天出一期重置mysql root密码的教程&#xff0c;适用于5.7和8.0&#xff0c;在网上搜索了很多的教程发现都没有效果&#xff0c;浪费了很多时间&#xff0c;尝试了多次之后发现这种方式是最稳妥的&#xff0c;那么废话不多说&#xff0c;往下看&#xff1a; 目录 第一步&…...

Linux下SVN客户端保存账号密码

参考文章&#xff1a;解决&#xff1a;Linux上SVN 1.12版本以上无法直接存储明文密码_linux svn 保存密码-CSDN博客新版本svn使用gpg-agent存储密码-CSDN博客svn之无法让 SVN 存储密码&#xff0c;即使配置设置为允许_编程设计_ITGUEST 方法一&#xff1a;明文方式保存密码 首…...

centos7.9 gcc升级到11.2.1

一、信息查看 # cat /etc/redhat-release CentOS Linux release 7.9.2009 (Core) # gcc --version gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-44) Copyright © 2015 Free Software Foundation, Inc. 本程序是自由软件&#xff1b;请参看源代码的版权声明。本软件没有任…...

HQChart使用教程30-K线图如何对接第3方数据42-DRAWTEXTREL,DRAWTEXTABS数据结构

HQChart使用教程30-K线图如何对接第3方数据42-DRAWTEXTREL,DRAWTEXTABS数据结构 效果图DRAWTEXTREL示例数据结构说明nametypecolorDrawVAlignDrawAlignDrawDrawTypeDrawDataFont DRAWTEXTABS示例数据结构说明nametypecolorDrawVAlignDrawAlignDrawDrawTypeDrawDataFont 效果图 …...

数仓高频面试 | 数仓为什么要分层

大家好&#xff0c;我是大D呀。 关于数仓分层&#xff0c;在面试过程中几乎是必问的。不过&#xff0c;面试官一般也不会直接考你数仓为什么要分层&#xff0c;而是在你介绍项目时&#xff0c;可能会换一种形式来穿插着问&#xff0c;比如数据链路为什么要这样设计&#xff0c…...

网络安全—部署CA证书服务器

网络拓扑 两台服务器在同一网段即可&#xff0c;即能够互相ping通。 安装步骤 安装证书系统 首先我们对计算机名进行确认&#xff0c;安装了证书系统后我们是不能随意更改计算机名字的&#xff0c;因为以后颁发的证书都是和计算机也就是这一台的服务器名字有关。 修改完成后开…...

MATLAB中circshift函数的原理分析——psf2otf函数的核心

之所以讲到MATLAB中circshift函数&#xff0c;也是源于Rafael Gonzalez的这个图&#xff0c;作为前几篇答廖老师问的blog的基础。 Rafael Gonzalez的这个图无论从哪幅图到哪幅图都不是直接的傅里叶变换或傅里叶逆变换&#xff0c;需要循环移位&#xff0c;即circshift函数。 这…...

js 惰性函数

惰性函数 是一种优化技术&#xff0c;主要用于避免重复判断和计算。它在第一次调用时确定最终的执行逻辑&#xff0c;并将其替换为适当的函数实现&#xff0c;从而在后续调用中跳过不必要的判断或初始化。 惰性函数的核心思想 第一次调用时执行初始化逻辑&#xff0c;并根据环…...

智能技术引领未来:自动图像标注的创新应用与发展

&#x1f351;个人主页&#xff1a;Jupiter. &#x1f680; 所属专栏&#xff1a;传知代码 欢迎大家点赞收藏评论&#x1f60a; 目录 概述算法原理核心逻辑效果演示使用方式参考文献 参考文献&#xff1a;需要本文的详细复现过程的项目源码、数据和预训练好的模型可从该地址处获…...

深入探索数据库世界:SQLite、Redis、MySQL 与数据库设计范式

数据库 深入探索数据库世界:SQLite、Redis、MySQL 与数据库设计范式一、SQLite 数据库全方位解析(一)创建与基本操作(二)数据存储与表结构设计(三)数据操作:增删改查(四)与 C 语言联合使用(五)防止 SQL 注入二、Redis 数据库深度剖析(一)数据存储类型与独特结构(…...

内网是如何访问到互联网的(华为源NAT)

私网地址如何能够访问到公网的&#xff1f; 在上一篇中&#xff0c;我们用任意一个内网的终端都能访问到百度的服务器&#xff0c;但是这是我们在互联网设备上面做了回程路由才实现的&#xff0c;在实际中&#xff0c;之前也说过运营商是不会写任何路由过来的&#xff0c;那对于…...

华为无线AC、AP模式与上线解析(Huawei Wireless AC, AP Mode and Online Analysis)

华为无线AC、AP模式与上线解析 为了实现fit 瘦AP的集中式管理&#xff0c;我们需要统一把局域网内的所有AP上线到AC&#xff0c;由AC做集中式管理部署。这里我们需要理解CAPWAP协议&#xff0c;该协议分为两种报文&#xff1a;1、管理报文 2、数据报文。管理报文实际在抓包过程…...

奖励模池化

奖励模池化 奖励模型概述 奖励模型(Reward Model)在机器学习,特别是强化学习领域中被广泛使用。它的主要作用是**对智能体(Agent)的行为进行评估并给予奖励。**例如,在训练一个机器人执行任务时,当机器人的动作符合预期目标(如成功抓取物品、按照正确路线行走等),奖励…...

基于django协同过滤的音乐推荐系统的设计与实现

一、摘要 随着现代音乐的快速发展&#xff0c;协同过滤的音乐推荐系统已成为人们业余生活的需求。该平台采用Python技术和django搭建系统框架&#xff0c;后台使用MySQL数据库进行信息管理&#xff1b;通过用户管理、音乐分类管理、音乐信息管理、歌曲数据管理、系统管理、我的…...

Tiptap,: 富文本编辑器入门与案例分析

Tiptap 是一个现代的富文本编辑器&#xff0c;基于 ProseMirror 打造&#xff0c;旨在提供一个灵活且功能强大的文本编辑解决方案。它具有开箱即用的能力&#xff0c;同时也允许开发者根据业务需求进行高度定制化扩展。与传统的富文本编辑器相比&#xff0c;Tiptap 提供了更精细…...

使用Linux的logrotate工具切割日志:Tomcat、NGINX(journal文件清理)

文章目录 引言I Tomcat日志切割配置轮转参数验证码II NGINX访问文件的配置和切割access.log 访问日志的配置使用Linux的logrotate工具切割日志验证文件切割III /run/log/journaljournalctl文件清理引言 journal文件清理: 只保留过去两天,清理之前的文件 journalctl --vacuu…...

CSS系列(11)-- 滤镜与混合模式详解

前端技术探索系列&#xff1a;CSS 滤镜与混合模式详解 &#x1f3a8; 致读者&#xff1a;探索视觉效果的艺术 &#x1f44b; 前端开发者们&#xff0c; 今天我们将深入探讨 CSS 滤镜与混合模式&#xff0c;学习如何创建独特的视觉效果。 滤镜效果详解 &#x1f680; 基础滤…...

linux - 存储管理

1.了解硬件 -- 磁盘 硬盘有机械硬盘(HDD)和固态硬盘(SDD) 接下来&#xff0c;主要以机械磁盘为例(更具代表性&#xff0c;在linux系统层面&#xff0c;无论是机械磁盘还是固态硬盘&#xff0c;文件的读取和写入都iNode(索引节点)管理文件的元数据和实际数据块) 1.盘片&#x…...

在 Kibana 中为 Vega Sankey 可视化添加过滤功能

作者&#xff1a;来自 Elastic Tim Bosman 及 Miloš Mandić 有兴趣在 Kibana 中为 Vega 可视化添加交互式过滤器吗&#xff1f;了解如何利用 “kibanaAddFilter” 函数轻松创建动态且响应迅速的 Sankey 可视化。 在这篇博客中&#xff0c;我们将了解如何启用 Vega Sankey 可视…...

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...

3.3.1_1 检错编码(奇偶校验码)

从这节课开始&#xff0c;我们会探讨数据链路层的差错控制功能&#xff0c;差错控制功能的主要目标是要发现并且解决一个帧内部的位错误&#xff0c;我们需要使用特殊的编码技术去发现帧内部的位错误&#xff0c;当我们发现位错误之后&#xff0c;通常来说有两种解决方案。第一…...

三体问题详解

从物理学角度&#xff0c;三体问题之所以不稳定&#xff0c;是因为三个天体在万有引力作用下相互作用&#xff0c;形成一个非线性耦合系统。我们可以从牛顿经典力学出发&#xff0c;列出具体的运动方程&#xff0c;并说明为何这个系统本质上是混沌的&#xff0c;无法得到一般解…...

EtherNet/IP转DeviceNet协议网关详解

一&#xff0c;设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络&#xff0c;本网关连接到EtherNet/IP总线中做为从站使用&#xff0c;连接到DeviceNet总线中做为从站使用。 在自动…...

SpringTask-03.入门案例

一.入门案例 启动类&#xff1a; package com.sky;import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCach…...

如何理解 IP 数据报中的 TTL?

目录 前言理解 前言 面试灵魂一问&#xff1a;说说对 IP 数据报中 TTL 的理解&#xff1f;我们都知道&#xff0c;IP 数据报由首部和数据两部分组成&#xff0c;首部又分为两部分&#xff1a;固定部分和可变部分&#xff0c;共占 20 字节&#xff0c;而即将讨论的 TTL 就位于首…...

大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计

随着大语言模型&#xff08;LLM&#xff09;参数规模的增长&#xff0c;推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长&#xff0c;而KV缓存的内存消耗可能高达数十GB&#xff08;例如Llama2-7B处理100K token时需50GB内存&a…...

学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”

2025年#高考 将在近日拉开帷幕&#xff0c;#AI 监考一度冲上热搜。当AI深度融入高考&#xff0c;#时间同步 不再是辅助功能&#xff0c;而是决定AI监考系统成败的“生命线”。 AI亮相2025高考&#xff0c;40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕&#xff0c;江西、…...

SiFli 52把Imagie图片,Font字体资源放在指定位置,编译成指定img.bin和font.bin的问题

分区配置 (ptab.json) img 属性介绍&#xff1a; img 属性指定分区存放的 image 名称&#xff0c;指定的 image 名称必须是当前工程生成的 binary 。 如果 binary 有多个文件&#xff0c;则以 proj_name:binary_name 格式指定文件名&#xff0c; proj_name 为工程 名&…...

JavaScript 数据类型详解

JavaScript 数据类型详解 JavaScript 数据类型分为 原始类型&#xff08;Primitive&#xff09; 和 对象类型&#xff08;Object&#xff09; 两大类&#xff0c;共 8 种&#xff08;ES11&#xff09;&#xff1a; 一、原始类型&#xff08;7种&#xff09; 1. undefined 定…...