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

news2024/11/26 16:29:52

框架介绍

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: 8088
    servlet:
        context-path: /sharding
spring:
    shardingsphere:
        datasource:
            names: db1,db2
            db1:
                driver-class-name: com.mysql.cj.jdbc.Driver
                type: com.zaxxer.hikari.HikariDataSource
                jdbc-url: jdbc:mysql://192.168.22.82:3306/order_db_1?useUnicode=true&useSSL=false
                username: root
                password: 123456
                validationQuery: SELECT 1 FROM DUAL
            db2:
                driver-class-name: com.mysql.cj.jdbc.Driver
                type: com.zaxxer.hikari.HikariDataSource
                jdbc-url: jdbc:mysql://192.168.22.82:3306/order_db_2?useUnicode=true&useSSL=false
                username: root
                password: 123456
                validationQuery: SELECT 1 FROM DUAL
        sharding:
            tables:
                t_order:
                    actual-data-nodes: db$->{1..2}.t_order_$->{1..3}
                    database-strategy:
#                        自定义分片策略
#                        complex:
#                            shardingColumns: user_id
#                            algorithmClassName: com.zdxlz.lwq.ShardingAlgorithm.ComplexRule
                        inline:
                            sharding-column: user_id
                            algorithm-expression: db$->{user_id % 2 + 1}
                    table-strategy:
                        inline:
                            sharding-column: price
                            algorithm-expression: t_order_$->{price % 3 + 1}
                    key-generator:
                        column: order_id
                        type: SNOWFLAKE
        props:
            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 {
    @TableId
    private 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> {
    @Override
    public Collection<String> doSharding(Collection<String> collection, ComplexKeysShardingValue<Integer> complexKeysShardingValue) {
        //collection返回数据库或数据表的集合,见yml配置的策略,此处返回的是数据库集合:[db1, db2]
        Collection<String> shardingResults = new ArrayList<>();
        //返回数据表的key、value
        Map<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,存db1
        if (userId>500){
            return 1;
        }else {
            //小于500,存db2
            return 2;
        }
    }

}

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

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

        sharding:
            tables:
                t_order:
                    actual-data-nodes: db$->{1..2}.t_order_$->{1..3}
                    database-strategy:
#                        自定义分片策略
                        complex:
                            shardingColumns: user_id
                            algorithmClassName: com.zdxlz.lwq.ShardingAlgorithm.ComplexRule
#                        inline:
#                            sharding-column: user_id
#                            algorithm-expression: db$->{user_id % 2 + 1}
                    table-strategy:
                        inline:
                            sharding-column: price
                            algorithm-expression: t_order_$->{price % 3 + 1}
                    key-generator:
                        column: order_id
                        type: 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.coloradmin.cn/o/1257568.html

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

相关文章

全球200大常用密码排行榜2023 一密码多达450万人使用

弱密码通常指的是容易被猜测、破解或者使用暴力攻击等手段获取的密码。弱密码对于账户和系统的安全性构成威胁&#xff0c;因为攻击者可以更容易地获取对受保护资源的访问权。以下是一些造成密码弱的常见原因&#xff1a; 短密码&#xff1a; 长度较短的密码更容易受到暴力破解…

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

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

Linux多线程基本概念

目录 ​编辑 1.什么是进程&#xff0c;线程&#xff0c;并发&#xff0c;并行 优点 缺点 什么资源是线程应该私有的呢 为什么线程切换成本更低呢 3.线程控制 pthread_create lpthread选项 makefile 代码实现 ps -aL 什么是LWP 轻量级进程ID与进程ID之间的区别 LWP与pthr…

【腾讯云云上实验室】用向量数据库—实践相亲社交应用

快速入口 &#x1f449;向量数据库_大模型知识库_向量数据存储_向量数据检索- 腾讯云 (tencent.com) 文章目录 前言1. 向量数据库概念及原理1.1 向量数据库概念1.2 向量数据库核心原理1.3 向量数据库优缺点1.4 向量数据库与传统数据库的区别 2. 腾讯云向量数据库的基本特性及优…

虹科方案 | 如何破解CAN与车载以太网之间数据传输和协议转换的难题?

导读&#xff1a;在车辆网络时代&#xff0c;数据传输和协议转换在通信领域中扮演着至关重要的角色。它们不仅能够实现车辆内部系统之间的互联互通&#xff0c;还支持车辆与外部网络进行通信&#xff0c;从而为驾驶者带来更智能、便捷的驾驶体验。本文将介绍CAN总线与车载以太网…

【JAVA届的一代神】——Spring框架体系及Spring IOC思想【面试常问!】

文章目录 Spring简介Spring体系结构SpringIOC控制反转思想自定义对象容器Spring实现IOCSpring容器类型容器接口容器实现类 对象的创建方式使用构造方法使用工厂类的方法使用工厂类的静态方法 对象的创建策略对象的销毁时机生命周期方法获取Bean对象的方式通过id/name获取通过类…

眼精星票证识别系统操作教程与技巧

眼精星票证识别系统是一款高效、准确的票证识别工具&#xff0c;可以帮助用户快速将各种票证识别成结构化数据&#xff0c;并支持批量合并导出Excel。该系统的使用非常简单&#xff0c;只需要按照以下步骤进行操作即可&#xff1a; 1. 下载并安装眼精星票证识别系统 来百度AP…

SSM图书捐赠网站系统开发mysql数据库web结构java编程计算机网页源码eclipse项目

一、源码特点 SSM 图书捐赠网站系统是一套完善的信息系统&#xff0c;结合springMVC框架完成本系统&#xff0c;对理解JSP java编程开发语言有帮助系统采用SSM框架&#xff08;MVC模式开发&#xff09;&#xff0c;系统具有完整的源代码和数据库 &#xff0c;系统主要采用B/…

深入理解 Docker 核心原理:Namespace、Cgroups 和 Rootfs

来自&#xff1a;探索云原生 https://www.lixueduan.com 原文&#xff1a;https://www.lixueduan.com/posts/docker/03-container-core/ 通过这篇文章你可以了解到 Docker 容器的核心实现原理&#xff0c;包括 Namespace、Cgroups、Rootfs 等三个核心功能。 后续文章会演示如…

k8s中安装consul集群

一、准备知识 headless services一般结合StatefulSet来部署有状态的应用&#xff0c;比如kafka集群&#xff0c;mysql集群&#xff0c;zk集群等&#xff0c;也包括本文要部署的consul集群。 0、consul集群 consul集群的分布式协议算法采用的是raft协议&#xff0c;这意味着必…

UI彩虹外链网盘系统整站源码/PHP网盘与外链分享程序/整站+模版文件

源码简介&#xff1a; 全新UI彩虹外链网盘系统源码&#xff0c;它是PHP网盘与外链分享程序&#xff0c;提供了整站模版文件&#xff0c;前后端美化模板。 彩虹外链网盘美化模板是一款专为PHP网盘和外链分享程序设计的模板。它具备多种功能&#xff0c;包括支持所有格式文件的…

记录本地与服务器之间数据传输方法(上传、下载文件)

文章目录 一、使用scp命令实现参数说明示例说明 二、使用工具实现windows系统苹果系统如有启发&#xff0c;可点赞收藏哟~ 一、使用scp命令实现 scp 是 secure copy &#xff08;安全复制&#xff09;的缩写, scp 是基于 ssh 登陆进行安全的远程文件拷贝命令。相当于 cp 命令 …

ChatGPT进阶:提示工程的神秘面纱与实战指南

文章目录 一、提示工程的概念与原理二、提示工程的实践方法三、提示工程的挑战与展望四、实战案例分析总结《ChatGPT进阶&#xff1a;提示工程入门》内容简介作者简介陈颢鹏&#xff1a;李子菡&#xff1a; 目录获取方式 在人工智能领域&#xff0c;对话系统已经成为了一个热门…

数智赋能 锦江汽车携手苏州金龙打造高质量盛会服务

作为一家老牌客运公司&#xff0c;成立于1956年的上海锦江汽车服务有限公司&#xff08;以下简称锦江汽车&#xff09;&#xff0c;拥有1200多辆大巴和5000多辆轿车&#xff0c;是上海乃至长三角地区规模最大的专业旅游客运公司。面对客运市场的持续萎缩&#xff0c;锦江汽车坚…

不用再羡慕“SpaceX“ 民营星际荣耀打造国产可回收火箭双曲线二号

大家好&#xff0c;我是极智视界&#xff0c;欢迎关注我的公众号&#xff0c;获取我的更多前沿科技分享 邀您加入我的知识星球「极智视界」&#xff0c;星球内有超多好玩的项目实战源码和资源下载&#xff0c;链接&#xff1a;https://t.zsxq.com/0aiNxERDq 大家似乎习惯了对马…

PDF不小心关闭没保存?这4个方法教你拯救文件!

“我刚刚在查看一个PDF文件&#xff0c;但是一不小心我就把它关闭了&#xff0c;而且我还忘记保存了。这可怎么办呢&#xff1f;PDF不小心关闭没保存应该怎么解决呢&#xff1f;还有办法恢复吗&#xff1f;” PDF文档是我们日常工作和学习中常用的文件格式&#xff0c;但有时候…

QQ录屏保存到哪了?教你快速找到保存位置

qq录屏是许多用户常用的屏幕录制工具&#xff0c;可是一旦录制结束&#xff0c;许多人不清楚如何找到和管理录制的视频文件。那么&#xff0c;您知道qq录屏保存到哪了吗&#xff1f;本文将深入研究qq录制视频功能&#xff0c;以帮助您了解如何存储和管理这些重要的录制视频文件…

【Android Gradle】之一小时 Gradle及 wrapper 入门

&#x1f604;作者简介&#xff1a; 小曾同学.com,一个致力于测试开发的博主⛽️&#xff0c;主要职责&#xff1a;测试开发、CI/CD 如果文章知识点有错误的地方&#xff0c;还请大家指正&#xff0c;让我们一起学习&#xff0c;一起进步。 &#x1f60a; 座右铭&#xff1a;不…

【算法萌新闯力扣】:合并两个有序链表

力扣题目&#xff1a;合并两个有序链表 开篇 今天是备战蓝桥杯的第24天及算法村开营第2天。根据算法村的讲义&#xff0c;来刷链表的相关题目。今天要分享的是合并两个有序链表。 题目链接: 21.合并两个有序链表 题目描述 代码思路 通过创建一个新链表&#xff0c;然后遍历…

DEM分析

一、实验名称&#xff1a; DEM分析 二、实验目的&#xff1a; 通过本实验练习&#xff0c;掌握DEM的建立与应用基本方法。 三、实验内容和要求&#xff1a; 实验内容&#xff1a; 利用ARCGIS软件相关分析工具及实验数据&#xff0c;创建DEM&#xff0c;并计算相应坡度的区…