二、Sharding-JDBC系列02:自定义主键生成策略

news2024/9/22 15:46:13

目录

一、概述

二、自定义主键生成策略

(1)、自定义MyShardingKeyGenerator

(2)、SPI接口配置

(3)、配置主键ID生成策略

(4)、测试数据插入


一、概述

实际应用中,大部分场景按照MySQL主键ID自增就能满足需求,但是在分库分表后,MySQL的自增主键就不能使用了,为了避免重复,我们需要全局唯一的ID,比如会员表的会员ID、订单表的订单ID等。

ShardingSphere不仅提供了内置的分布式主键生成器,例如UUID、SNOWFLAKE,默认使用SNOWFLAKE,其对应实现类如下:

public final class UUIDShardingKeyGenerator implements ShardingKeyGenerator {
    // UUID: 采用UUID.randomUUID()的方式产生分布式主键
}

public final class SnowflakeShardingKeyGenerator implements ShardingKeyGenerator {
// SNOWFLAKE: 雪花算法,生成64bit的长整型数据
}

还抽离出分布式主键生成器的接口,方便用户自行实现自定义的自增主键生成器。通过观察sharding-jdbc源码,可以看到这两种主键ID生成策略都是实现了ShardingKeyGenerator接口,可以看到,如果我们需要自定义主键生成策略,只需要实现ShardingKeyGenerator接口,然后实现其中的如下方法: 

public class XXX implements ShardingKeyGenerator {
    @Override
    public Comparable<?> generateKey() {
        // 实现自定义主键生成规则,自定义实现
        return null;
    }

    @Override
    public String getType() {
		// 指定主键生成的类型,对应到sharding-jdbc分片规则中的defaultKeyGenerator.type或者keyGenerator.type的值
        return null;
    }

    @Override
    public Properties getProperties() {
        return null;
    }

    @Override
    public void setProperties(Properties properties) {

    }
}

通过查看sharding-jdbc源码中主键生成策略类的引用,我们发现sharding-jdbc利用了spi机制来支持用户自定义主键生成策略,也就是在项目resources/META-INF/services目录下创建名为org.apache.shardingsphere.spi.keygen.ShardingKeyGenerator的文件,文件的值就写上我们自定义主键策略的全限定类名。

二、自定义主键生成策略

(1)、自定义MyShardingKeyGenerator

自定义主键ID生成策略为:当前日期拼接上UUID随机字符串。 

public final class MyShardingKeyGenerator implements ShardingKeyGenerator {

    private static Logger logger = LoggerFactory.getLogger(MyShardingKeyGenerator.class);

    private Properties properties = new Properties();

    @Override
    public Comparable<?> generateKey() {
        logger.info("execute MyShardingKeyGenerator.generateKey()");
        String nowDate = new SimpleDateFormat("yyyyMMdd").format(new Date());
        String uuid = UUID.randomUUID().toString();
        return nowDate + uuid;
    }

    @Override
    public String getType() {
        return "MyUUID";
    }

    @Override
    public Properties getProperties() {
        return properties;
    }

    @Override
    public void setProperties(Properties properties) {
        this.properties = properties;
    }
}

(2)、SPI接口配置

在Apache ShardingSphere中,很多功能实现类的加载方式是通过SPI注入的方式完成的。Service Provider Interface (SPI)是一种为了被第三方实现或扩展的API,它可以用于实现框架扩展或组件替换。

为了让用户通过实现Apache ShardingSphere提供的相应接口,动态将用户自定义的实现类加载其中,从而在保持Apache ShardingSphere架构完整性与功能稳定性的情况下,满足用户不同场景的实际需求。

在resources目录下新建META-INF文件夹,再新建services文件夹,然后新建文件的名字为org.apache.shardingsphere.spi.keygen.ShardingKeyGenerator的文件【META-INF/services/org.apache.shardingsphere.spi.keygen.ShardingKeyGenerator】,文件内容为自定义主键生成策略的全限定类名【org.example.shardingjdbcdemo.algorithm.MyShardingKeyGenerator】

(3)、配置主键ID生成策略 

spring:
  shardingsphere:
    props:
      sql:
        show: true  # 打印具体的插入SQL
    datasource:
      names: ds0,ds1
      ds0: # 数据源的名称
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.jdbc.Driver
        url: jdbc:mysql://127.0.0.1:3306/order_db0?useUnicode=true&characterEncoding=utf8&tinyInt1isBit=false&useSSL=false&serverTimezone=GMT
        username: root
        password: "0905"
      ds1: # 数据源的名称
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.jdbc.Driver
        url: jdbc:mysql://127.0.0.1:3306/order_db1?useUnicode=true&characterEncoding=utf8&tinyInt1isBit=false&useSSL=false&serverTimezone=GMT
        username: root
        password: "0905"
    sharding:
      tables:
        t_dictionary:  # 全局广播表
          key-generator:
            column: id   # 主键字段名称
            type: MyUUID # 主键生成策略:MyUUID。对应自定义主键生成策略的MyShardingKeyGenerator.getType的返回值
      default-data-source-name: ds0  # 默认数据源
      default-table-strategy:  # 默认分表策略
        none:
      broadcast-tables: t_dictionary   # 广播表

 

(4)、测试数据插入

从控制台日志输出,我们也看到了,执行了自定义主键生成策略MyShardingKeyGenerator的逻辑,并且生成的ID也自动拼接了当前日期,这就是sharding-jdbc自定义主键生成策略的思路。

2023-12-21 11:02:54.518  INFO 18372 --- [           main] o.e.s.algorithm.MyShardingKeyGenerator   : execute MyShardingKeyGenerator.generateKey()
2023-12-21 11:02:55.637  INFO 18372 --- [           main] ShardingSphere-SQL                       : Logic SQL: insert into t_dictionary(`code`,  `value`) values (?, ?)
2023-12-21 11:02:55.637  INFO 18372 --- [           main] ShardingSphere-SQL                       : SQLStatement: InsertStatementContext(super=CommonSQLStatementContext(sqlStatement=org.apache.shardingsphere.sql.parser.sql.statement.dml.InsertStatement@4fc165f6, tablesContext=org.apache.shardingsphere.sql.parser.binder.segment.table.TablesContext@545b5ed0), tablesContext=org.apache.shardingsphere.sql.parser.binder.segment.table.TablesContext@545b5ed0, columnNames=[code, value], insertValueContexts=[InsertValueContext(parametersCount=2, valueExpressions=[ParameterMarkerExpressionSegment(startIndex=51, stopIndex=51, parameterMarkerIndex=0), ParameterMarkerExpressionSegment(startIndex=54, stopIndex=54, parameterMarkerIndex=1), DerivedParameterMarkerExpressionSegment(super=ParameterMarkerExpressionSegment(startIndex=0, stopIndex=0, parameterMarkerIndex=2))], parameters=[type, normal])], generatedKeyContext=Optional[GeneratedKeyContext(columnName=id, generated=true, generatedValues=[20231221dbce01cc-c0c7-43b7-aa47-014c1c6ed29d])])
2023-12-21 11:02:55.638  INFO 18372 --- [           main] ShardingSphere-SQL                       : Actual SQL: ds0 ::: insert into t_dictionary(`code`,  `value`, id) values (?, ?, ?) ::: [type, normal, 20231221dbce01cc-c0c7-43b7-aa47-014c1c6ed29d]
2023-12-21 11:02:55.638  INFO 18372 --- [           main] ShardingSphere-SQL                       : Actual SQL: ds1 ::: insert into t_dictionary(`code`,  `value`, id) values (?, ?, ?) ::: [type, normal, 20231221dbce01cc-c0c7-43b7-aa47-014c1c6ed29d]

 

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

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

相关文章

弟12章 1 网络编程

文章目录 网络协议概述 p164TCP协议与UDP协议的区别 p165 网络协议概述 p164 ipv4&#xff1a;十进制点分制 ipv6&#xff1a;十六进制冒号分隔 TCP协议与UDP协议的区别 p165 tcp协议的三次握手&#xff1a;

双向冒泡排序的数据结构实验报告

目录 实验目的&#xff1a; 实验内容&#xff08;实验题目与说明&#xff09; 算法设计&#xff08;核心代码或全部代码&#xff09; 运行与测试&#xff08;测试数据和实验结果分析&#xff09; 总结与心得&#xff1a; 实验目的&#xff1a; 理解双向冒泡排序算法的原…

FreeRTOS 学习相关笔记 附C语言内容补充

学习视频为【正点原子】手把手教你学FreeRTOS实时系统 文章目录 RTOS 入门裸机RTOSFreeRTOS任务调度方式任务状态 FreeRTOS 移植系统配置文件 API函数任务创建和删除动态方式创建任务静态方式创建任务删除任务 任务挂起和恢复函数调度器挂起与恢复临界区任务调度器的挂起和恢复…

估算监控最低可以存储的时长

监控可以存储的时长&#xff0c;主要取决于码率&#xff0c;知道了码率就知道一天可以的视频产生多少视频数据。 以乐橙官网给出的计算&#xff0c;我们可以推出这个设备8MP本地的录像码率大概在4Mbps左右。 同样的我们这里附一张表格&#xff0c;大家可以根据这个来估算存储…

leetcode14. 最长公共前缀

题目 编写一个函数来查找字符串数组中的最长公共前缀。 如果不存在公共前缀&#xff0c;返回空字符串 “”。 解题方法&#xff1a; 1.首先找到数组中长度最短的数据&#xff0c;与数组第一个数进行交换&#xff08;公共前缀的长度肯定不会大于列表中长度最短的字符串&#x…

大模型实战营Day3 作业

基础作业&#xff1a; 复现课程知识库助手搭建过程 (截图) 进阶作业&#xff1a; 选择一个垂直领域&#xff0c;收集该领域的专业资料构建专业知识库&#xff0c;并搭建专业问答助手&#xff0c;并在 OpenXLab 上成功部署&#xff08;截图&#xff0c;并提供应用地址&#xf…

pyenv虚拟环境安装和配合pipenv多版本创建

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、下载配置pyenv二、配置多版本虚拟环境总结 前言 最近公司编写了一个自动化用例编写软件&#xff0c;需要适配win7和win10系统&#xff0c;需要同时编译3.8…

Nacos和Eureka比较、统一配置管理、Nacos热更新、多环境配置共享、Nacos集群搭建步骤

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、Nacos和eureka的对比二、统一配置管理二、Nacos热更新方式一方式二 三、多环境配置共享四、Nacos集群搭建步骤&#xff08;黑马springCloud的p29&#xff0…

如何实现接口重试

重试机制 在复杂的接口业务中&#xff0c;API请求数量很多&#xff0c;并且业务处理复杂&#xff0c;便难免会遇到一些网络问题(timeout)或者未知错误(error)&#xff0c;这时候需要加入重试机制了。让我们来回顾一下都有什么实现机制吧。 8种重试机制实现 1. 循环重试 这是最…

基于SSM+JSP的订餐管理系统的设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

不方便拉网线,房间又没Wifi信号?按照这个教程,让你家里每个角落都有网

前言 前段时间去了一个朋友家里&#xff0c;她老是和我叨叨说她家的卧室一点Wifi信号都没有。每次一躺床上都只能用手机流量上网。 家里明明有拉宽带&#xff0c;为什么在某一些地方还是得用自己手机流量&#xff1f;哎&#xff0c;有钱人的痛就是房子太大了。 我问她为啥不多…

Open3D 从体素网格构建八叉树(14)

Open3D 从体素网格构建八叉树(14) 一、算法简介二、算法实现1.代码2.效果一、算法简介 上一章介绍从点云构建八叉树,对点云所在体素进行了可视化显示,这里可以对体素构建八叉树,可视化显示八叉树的具体划分结构。 二、算法实现 1.代码 代码如下(示例): import op…

微服务治理:微服务断路器(微服务故障隔离模式)详解

微服务断路器是一种设计模式&#xff0c;可以保护系统免于级联故障&#xff0c;通过限制对故障服务的调用来实现。它的工作原理类似于电气断路器&#xff1a;当服务遇到问题时&#xff0c;它会切断请求流&#xff0c;使其有机会恢复&#xff0c;并防止其他服务被压垮。 工作原…

opencv3.4.12全景拼接

最近camera项目需要用到全景拼接&#xff0c;故此查阅大量资料&#xff0c;终于将此功能应用在实际项目上&#xff0c;下面总结一下此过程中遇到的一些问题及解决方式&#xff0c;同时也会将源码附在结尾处&#xff0c;供大家参考。 首先说一下此源码的大概执行流程&#xff0c…

Nginx服务配置文件

在Nginx服务器的主配置文件/usr/local/nginx/conf/nginx.conf 中&#xff0c;包括全局配置、I/O事件配置 和HTTP配置这三大块内容&#xff0c;配置语句的格式为“关键字 值&#xff1a;”&#xff08;末尾以分号表示结束&#xff09;&#xff0c;以“#” 开始的部分表示注释。 …

FreeRTOS系统配置

一、前言 在实际使用FreeRTOS 的时候我们时常需要根据自己需求来配置FreeRTOS&#xff0c;而且不同架构 的MCU在使用的时候配置也不同。FreeRTOS的系统配置文件为FreeRTOSConfig.h&#xff0c;在此配置文件中可以完成FreeRTOS的裁剪和配置&#xff0c;这是非常重要的一个文件&a…

Qt/QML编程学习之心得:Grid、GridLayout、GridView、Repeater(33)

GRID网格用处非常大,不仅在excel中,在GUI中,也是非常重要的一种控件。 Grid 网格是一种以网格形式定位其子项的类型。网格创建一个足够大的单元格网格,以容纳其所有子项,并将这些项从左到右、从上到下放置在单元格中。每个项目都位于其单元格的左上角,位置为(0,0)。…

【自学笔记】01Java基础-08Java常用API:02Object类详解

>什么是API&#xff1f; 1 Object类 Object类是所有Java类的根父类&#xff0c;无论是否显式声明&#xff0c;所有的Java类都直接或间接地继承自java.lang.Object。 1.1 Object类的作用 统一规范&#xff1a;为所有Java对象提供了一组基本方法&#xff0c;使得任何Java对…

【图解面试】JS系列 - 如何回答数据类型相关问题(上)

1. JS中的数据类型有哪些&#xff0c;他们的区别是什么&#xff1f; 知识点大纲 语言组织&#xff08;示例&#xff09; 要点&#xff1a;数量 → 种类 → 区别 JS中的数据类型主要有 8 种&#xff0c;分为两大类 基础数据类型 和 引用数据类型 基础数据类型中主要有 Numbe…

力扣热题100

排序 快速排序 #include <iostream> #include <vector> using namespace std;// 快速排序函数&#xff0c;传入引用&#xff0c;以便修改原始数组 void quick_sort(vector<int>& q, int l, int r) {// 边界条件&#xff1a;如果左边界大于等于右边界&am…