ShardingSphere-JDBC 入门教程(v4.1.1)

框架介绍

ShardingSphere-JDBC 定位为轻量级 Java 框架,在 Java 的 JDBC 层提供的额外服务。它使用客户端直连数据库,以 jar 包形式提供服务,无需额外部署和依赖,可理解为增强版的 JDBC 驱动,完全兼容 JDBC 和各种 ORM 框架。

具备以下功能:

特性

定义

数据分片

数据分片,是应对海量数据存储与计算的有效手段。ShardingSphere 基于底层数据库提供分布式数据库解决方案,可以水平扩展计算和存储。

分布式事务

事务能力,是保障数据库完整、安全的关键技术,也是数据库的核心技术。基于 XA 和 BASE 的混合事务引擎,ShardingSphere 提供在独立数据库上的分布式事务功能,保证跨数据源的数据安全。

读写分离

读写分离,是应对高压力业务访问的手段。基于对 SQL 语义理解及对底层数据库拓扑感知能力,ShardingSphere 提供灵活的读写流量拆分和读流量负载均衡。

数据迁移

数据迁移,是打通数据生态的关键能力。ShardingSphere 提供跨数据源的数据迁移能力,并可支持重分片扩展。

联邦查询

联邦查询,是面对复杂数据环境下利用数据的有效手段。ShardingSphere 提供跨数据源的复杂查询分析能力,实现跨源的数据关联与聚合。

数据加密

数据加密,是保证数据安全的基本手段。ShardingSphere 提供完整、透明、安全、低成本的数据加密解决方案。

影子库

在全链路压测场景下,ShardingSphere 支持不同工作负载下的数据隔离,避免测试数据污染生产环境。

更多信息见官网:概览 :: ShardingSphere

快速集成

开发环境:JDK 1.8、Maven 3.8.8、 IDEA CE 2023.2、MySQL 8.0.34

实现目标:使用 ShardingSphere-JDBC 进行数据库的分库分表,以 4.1.1 为例

技术架构:SpringBoot+MyBatis-Plus+ShardingSphere-JDBC

数据库结构:

order_db_1:

t_order_1

t_order_2

t_order_3

order_db_2:

t_order_1

t_order_2

t_order_3

两个数据库下的表结构完全相同,建表语句见下:

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 '订单状态',`create_date` datetime DEFAULT NULL,PRIMARY KEY (`order_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

pom 文件配置依赖:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.zdxlz.lwq</groupId><artifactId>sharding-jdbc-demo</artifactId><version>1.0-SNAPSHOT</version><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.6.2</version><relativePath/> <!-- lookup parent from repository --></parent><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.1</version></dependency><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><version>8.0.32</version><scope>compile</scope></dependency><dependency><groupId>org.apache.shardingsphere</groupId><artifactId>sharding-jdbc-spring-boot-starter</artifactId><version>4.1.1</version></dependency></dependencies></project>

yml 文件配置数据库相关信息:

server:port: 8088servlet:context-path: /sharding
spring:shardingsphere:datasource:names: db1,db2db1:driver-class-name: com.mysql.cj.jdbc.Drivertype: com.zaxxer.hikari.HikariDataSourcejdbc-url: jdbc:mysql://192.168.22.82:3306/order_db_1?useUnicode=true&useSSL=falseusername: rootpassword: 123456validationQuery: SELECT 1 FROM DUALdb2:driver-class-name: com.mysql.cj.jdbc.Drivertype: com.zaxxer.hikari.HikariDataSourcejdbc-url: jdbc:mysql://192.168.22.82:3306/order_db_2?useUnicode=true&useSSL=falseusername: rootpassword: 123456validationQuery: SELECT 1 FROM DUALsharding:tables:t_order:actual-data-nodes: db$->{1..2}.t_order_$->{1..3}database-strategy:
#                        自定义分片策略
#                        complex:
#                            shardingColumns: user_id
#                            algorithmClassName: com.zdxlz.lwq.ShardingAlgorithm.ComplexRuleinline:sharding-column: user_idalgorithm-expression: db$->{user_id % 2 + 1}table-strategy:inline:sharding-column: pricealgorithm-expression: t_order_$->{price % 3 + 1}key-generator:column: order_idtype: SNOWFLAKEprops:sql:show: true

yml 文件中的配置项需要仔细确认,例如数据库的地址应使用 jdbc-url 而非 url,在只有单个数据源时,SpringBoot 走默认数据源逻辑为我们把 url 与 jdbc-url 进行映射,保证我们获得数据源。此时我们自己设置的数据源没有进行映射处理,就需要保证字段符合Hikari的要求。否则会出现 java.lang.IllegalArgumentException: jdbcUrl is required with driverClassName 异常。还需要明确指定 type,否则会提示 shardingDataSource 创建失败,配置参考见:数据源配置 :: ShardingSphere

分库分表

在上文中的 yml 文件中,sharding.tables.t_order 中已配置分库分表的策略,用 groovy 语法实现。

ShardingSphere-JDBC 分库/分表策略支持 standard(用于单分片键的标准分片场景)、complex(用于多分片的复合分片场景)、inline(行表达式分片策略),详细介绍见:Yaml配置 :: ShardingSphere

以上文最简单的 inline 说明:

shardingColumn 为分片列名称,即以该字段进行逻辑处理,进行分数据库/数据表

algorithm-expression 为 groovy 语法实现的行表达式,是该字段的具体逻辑操作

对于配置在 database-strategy 下的 inline 实现的效果是:对于插入的数据,进行 user_id 判断,如果 user_id 整除 2,数据插入到 db_1,否则插入到db_2

对于配置在 table-strategy 下的 inline 实现的效果是:对于插入的数据,进行  price 判断,如果 price_id 整除 3,数据插入到 t_order_1,否则余数 +1 分别插入到 t_order_2、t_order_3

至此完成新增数据的分配,将大量数据分别通过 user_id、price 判断,分配到 2 个数据库的 6 个表下面,完成分库分表

对于分库分表的详细介绍可见:核心概念 :: ShardingSphere

注意点:对于业务代码的实现,数据库的真实表为 t_order_1、 t_order_2、 t_order_3,参考 ShardingSphere-JDBC 处理实现,我们构建数据库实体类时,@TableName 设定为 t_order 即可,示例:

package com.zdxlz.lwq.enity;import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;import java.math.BigDecimal;
import java.util.Date;@TableName("t_order")
public class Order {@TableIdprivate BigDecimal order_id;@TableField("price")private int price;@TableField("user_id")private int user_id;@TableField("status")private String status;@TableField("create_date")private Date create_date;public BigDecimal getOrder_id() {return order_id;}public void setOrder_id(BigDecimal order_id) {this.order_id = order_id;}public int getPrice() {return price;}public void setPrice(int price) {this.price = price;}public int getUser_id() {return user_id;}public void setUser_id(int user_id) {this.user_id = user_id;}public String getStatus() {return status;}public void setStatus(String status) {this.status = status;}public Date getCreate_date() {return create_date;}public void setCreate_date(Date create_date) {this.create_date = create_date;}
}

自定义分库分表策略

对于 groovy 语法不好实现、难以实现的逻辑,可以采用 complex 模式,自定义实现分片策略,示例如下:

package com.zdxlz.lwq.ShardingAlgorithm;import org.apache.shardingsphere.api.sharding.complex.ComplexKeysShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.complex.ComplexKeysShardingValue;import java.util.*;public class ComplexRule implements ComplexKeysShardingAlgorithm<Integer> {@Overridepublic Collection<String> doSharding(Collection<String> collection, ComplexKeysShardingValue<Integer> complexKeysShardingValue) {//collection返回数据库或数据表的集合,见yml配置的策略,此处返回的是数据库集合:[db1, db2]Collection<String> shardingResults = new ArrayList<>();//返回数据表的key、valueMap<String, Collection<Integer>> columnsMap = complexKeysShardingValue.getColumnNameAndShardingValuesMap();//columnsMap返回插入数据的key和value,key为complex中配置的shardingColumns字段值,此处返回为{user_id=[617]}List userIds = Arrays.asList(columnsMap.get("user_id").toArray());for (Object userId:userIds) {//对user_id进行逻辑处理int index = getIndex((Integer) userId);//循环匹配数据表源for (String availableTargetName : collection){if (availableTargetName.endsWith(String.valueOf(index))) {shardingResults.add(availableTargetName);break;}}//匹配到一种路由规则就可以退出
//            if (shardingResults.size() > 0) {
//                break;
//            }}//返回匹配到的数据库:shardingResults:[db_2],数据表同理return shardingResults;}public int getIndex (int userId) {//大于500,存db1if (userId>500){return 1;}else {//小于500,存db2return 2;}}}

首先实现 ComplexKeysShardingAlgorithm<T> ,根据要处理的字段选择相应数据类型。

根据 yml 中的配置,确定处理数据库或数据表,示例中的 yml 配置

        sharding:tables:t_order:actual-data-nodes: db$->{1..2}.t_order_$->{1..3}database-strategy:
#                        自定义分片策略complex:shardingColumns: user_idalgorithmClassName: com.zdxlz.lwq.ShardingAlgorithm.ComplexRule
#                        inline:
#                            sharding-column: user_id
#                            algorithm-expression: db$->{user_id % 2 + 1}table-strategy:inline:sharding-column: pricealgorithm-expression: t_order_$->{price % 3 + 1}key-generator:column: order_idtype: SNOWFLAKE

对数据库进行自定义分片,对字段 user_id 的值进行逻辑处理,选择对应的数据库

因此方法 doSharding( ) 参数 collection 返回数据库集合:[db1, db2]

columnsMap 返回插入数据的 key 和 value,key 为 complex中配置的 shardingColumns字段值 user_id,此处返回为{user_id=[617]}

逻辑匹配后,最终返回的数据库 shardingResults:[db2]

即表明该条数据将插入到 db2 中

对于数据表想实现自定义分片策略,同上述操作一致,仅需在 table-strategy 下配置 complex,然后自定义实现相关逻辑

开源项目地址:GitHub - liuweiqiang2016/shardingjdbc-demo: 分库分表开源框架shardingjdbc入门学习

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

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

相关文章

利用ogr2ogr从PostGIS中导出/导入Tab/Dxf/Geojson等格式数据

ogr2ogr Demo Command 先查看下当前gdal支持的全部格式&#xff0c;部分gdal版本可能不支持PostGIS。 如出现PostgreSQL表名支持。 #全部支持的格式 ogrinfo --formats | sort #AVCBin -vector- (rov): Arc/Info Binary Coverage #AVCE00 -vector- (rov): Arc/Info E00 (ASC…

数据结构——动态规划

动态规划&#xff1a;有很多重叠子问题&#xff0c;每一个状态一定是由上一个状态推导出来的 贪心&#xff1a;没有状态推导&#xff0c;而是从局部直接选最优的 动规五步曲&#xff1a; 确定dp数组&#xff08;dp table&#xff09;以及下标的含义 确定递推公式&#xff08;容…

STM32-SPI1控制AD7705(Sigma-Delta-ADC芯片)

STM32-SPI1控制AD7705&#xff08;Sigma-Delta-ADC芯片&#xff09; 原理图手册说明功能方框图引脚功能 片内寄存器通信寄存器&#xff08;RS2、RS1、RS00、0、0&#xff09;设置寄存器时钟寄存器数据寄存器&#xff08;RS2、RS1、RS00、1、1&#xff09;测试寄存器&#xff08…

SAP Smartforms设计

第八章 SMART FORMS设计 要点列表 概览&#xff1b; Form&#xff08;表格&#xff09;&#xff1b; Smart Styles&#xff08;样式&#xff09;&#xff1b; Text Module&#xff08;文本模块&#xff09;&#xff1b; 使用标准表方式打印&#xff1b; 使用模板方式打印…

淼一科技为互联网企业销毁硬盘数据 拆除机房设备

在上海这座繁华的大都市&#xff0c;淼一科技以其专业的服务和卓越的技术&#xff0c;为众多互联网企业提供硬盘数据销毁和机房设备拆除服务。作为业界领先的数据安全解决方案提供商&#xff0c;淼一科技致力于保障客户数据的安全与隐私&#xff0c;为客户创造更高的商业价值。…

leetcode周赛373场

leetcode周赛373场 第三题2948题 评论区的解题思路找到了很好的解法&#xff0c;当时没有想到&#xff0c;给原始数组排序后&#xff0c;分段再给数组位置排序。 class Solution {public int[] lexicographicallySmallestArray(int[] nums, int limit) {int n nums.length;I…

uni-app:心跳机制基础逻辑(定时器方法解决)

思路 1、在登录的时候&#xff0c;定义一个存储当前时间的全局变量&#xff0c;并且开始心跳请求 2、在全局中定义一个定时器&#xff0c;该定时器每秒都会执行一次&#xff0c;并获取当前的时间 3、将定时器每秒的获取的当前时间和全局变量获取的时间进行比较 4、指定一个…

网络运维与网络安全 学习笔记2023.11.27

网络运维与网络安全 学习笔记 第二十八天 今日目标 OSPF基本原理、OSPF单区域配置、OSPF多区域配置 特殊区域之Stub、特殊区域之NSSA OSPF基本原理 项目背景 随着企业的发展&#xff0c;网络的规模越来越大&#xff0c;网段的数量越来越多&#xff0c;公司内部的路由器的…

Windows系统下搭建PXE Server

在给一台服务器初始安装OS时一般有以下几种方式&#xff1a; 1、通过BMC挂载iso镜像来安装&#xff1b; 2、通过U盘启动来安装&#xff1b; 3、通过网络启动来安装&#xff1b; 方式1和方式2只能一台一台地进行&#xff0c;且需要有键盘和显示器&#xff0c;效率低下&#xff…

在vue页面中添加组件到底有多方便

修改vue写的前端页面到底有多方便&#xff1f;如果熟练的话&#xff0c;出乎你想象的快。 原来的页面&#xff1a;/admin/stock 原来的文件地址&#xff1a;src\views\admin\stock\Stock.vue 另一个页面有个入库功能&#xff0c;需要转移到上面的页面中&#xff1a; 路径&…

基于C#实现块状链表

在数据结构的世界里&#xff0c;我们会认识各种各样的数据结构&#xff0c;每一种数据结构都能解决相应领域的问题&#xff0c;当然每个数据结构&#xff0c;有他的优点&#xff0c;必然就有它的缺点&#xff0c;那么如何创造一种数据结构来将某两种数据结构进行扬长避短&#…

Java代码生成器,一键在线生成,支持自定义模板

【Java代码生成神器】自动化生成Java实体类、代码、增删改查功能&#xff01;点击访问 推荐一个自己每天都在用的Java代码生成器&#xff01;这个网站支持在线生成Java代码&#xff0c;包含完整的Controller\Service\Entity\Dao代码&#xff0c;完整的增删改查功能&#xff01…

金鸣表格文字识别客户端输出项该如何选择?

智能布局&#xff1a;根据提交的图片自动设置输出的打印纸张大小和方向&#xff0c;其中表格识别默认为A4纵向&#xff0c;勾选“合并”可将N张图片批量识别成一个文件、一个表。 表格识别&#xff1a; excel&#xff1a;输出可编辑的excel。 word&#xff1a;输出可编辑的w…

10G以太网接口的FPGA实现,你需要的都在这里

参考链接&#xff1a;10G以太网接口的FPGA实现&#xff0c;你需要的都在这里 - 知乎

机器人分类

从发展阶段分类&#xff1a; 1第一代机器人2第二代机器人3第三代机器人&#xff1a;智能型机器人。生于90年代。具有传感器&#xff0c;以前的机器人都不具有传感器 从控制方式分类&#xff1a;&#xff08;我觉得这个分类好乱&#xff09; 操作型机器人&#xff1a;可自动控…

机器学习的复习笔记1

机器学习是一种人工智能的分支&#xff0c;它通过让计算机从数据中学习规律和模式&#xff0c;从而实现对未知数据的预测和决策。根据不同的学习方法和任务&#xff0c;机器学习可以分为以下几种类型&#xff1a; 监督学习&#xff1a;在监督学习中&#xff0c;计算机会被提供一…

稳定扩散模型的隐空间探索

生成图像模型学习视觉世界的“潜在流形”&#xff1a;每个点映射到图像的低维向量空间。 从流形上的这样一个点回到可显示的图像称为“解码”—在稳定扩散模型中&#xff0c;这是由“解码器”模型处理的。 在线工具推荐&#xff1a; Three.js AI纹理开发包 - YOLO合成数据生成器…

为什么MES管理系统实施效果会很差

随着制造业的快速发展&#xff0c;MES生产管理系统越来越受到企业的关注。MES管理系统是一种面向车间生产的管理系统&#xff0c;用于在产品从工单发出到成品完工的过程中传递信息&#xff0c;以优化生产活动并提高操作及流程的效率。然而&#xff0c;很多公司在使用MES管理系统…

林业无人机如何提升巡山护林效率?

在郁郁森林之上&#xff0c;一架无人机正盘旋在上空时刻观察着林区的情况。凭借复亚智能的全自动巡检系统&#xff0c;无人机巡山护林的巡视范围和反馈实时性得到了显著提升。 一、林业无人机&#xff1a;科技赋能森林防火 秋季林区时常发生火灾&#xff0c;林业无人机在森林防…

WordPress最廉价优化整站的加载速度

为什么说一个站不优化就等于一个人做整个团队的事务导致项目进展慢&#xff0c;网站也是如此 图片、静态文件、php分离加速&#xff0c;加载速度并不是很快但是很协调比单个网站加载速度快许多 一、图片单域名加载设置上传文件路径和域名 以下代码添加在主题目录&#xff1a;fu…