ShardingSphere (一)

news2025/7/15 19:12:41

ShardingSphere (一)

ShardingSphere-JDBC 与 SpringBoot 集成

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

适用于任何基于 JDBC 的 ORM 框架,如:JPA, Hibernate, Mybatis, Spring JDBC Template 或直接使用 JDBC;
支持任何第三方的数据库连接池,如:DBCP, C3P0, BoneCP, HikariCP 等;
支持任意实现 JDBC 规范的数据库,目前支持 MySQL,PostgreSQL,Oracle,SQLServer 以及任何可使用 JDBC 访问的数据库。

分库

通过配置user_id将不同的数据存入不同的库表中

依赖配置

<dependency>
     <groupId>org.apache.shardingsphere</groupId>
     <artifactId>shardingsphere-jdbc-core-spring-boot-starter</artifactId>
     <version>5.2.1</version>
 </dependency>
 <dependency>
     <groupId>org.yaml</groupId>
     <artifactId>snakeyaml</artifactId>
     <version>1.33</version>
 </dependency>
 <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-data-jpa</artifactId>
 </dependency>
 <dependency>
     <groupId>mysql</groupId>
     <artifactId>mysql-connector-java</artifactId>
 </dependency>
 <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-test</artifactId>
 </dependency>
 <dependency>
     <groupId>junit</groupId>
     <artifactId>junit</artifactId>
 </dependency>

如果出现以下错误,则需引入 snakeyaml版本为1.33

Caused by: java.lang.NoSuchMethodError: 'void org.apache.shardingsphere.infra.util.yaml.constructor.ShardingSphereYamlConstructor$1.setCodePointLimit(int)'
	at org.apache.shardingsphere.infra.util.yaml.constructor.ShardingSphereYamlConstructor$1.<init>(ShardingSphereYamlConstructor.java:44)
	at org.apache.shardingsphere.infra.util.yaml.constructor.ShardingSphereYamlConstructor.<init>(ShardingSphereYamlConstructor.java:41)
	at org.apache.shardingsphere.infra.util.yaml.YamlEngine.unmarshal(YamlEngine.java:83)

application.yml 配置

spring:
  shardingsphere:
    datasource:
      names: ds-0, ds-1
      ds-0:
        type: com.zaxxer.hikari.HikariDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        jdbc-url: jdbc:mysql://192.168.79.177:14306/datas_0?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8
        username: root
        password: 123456
      ds-1:
        type: com.zaxxer.hikari.HikariDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        jdbc-url: jdbc:mysql://192.168.79.177:14306/datas_1?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8
        username: root
        password: 123456
    rules:
      sharding:
        default-database-strategy:
          standard:
            # 以字段分片
            sharding-column: user_id
            # 分片算法名称,可自定义
            sharding-algorithm-name: db-inline
        # 绑定广播表,多库存在此表且数据一致
        broadcast-tables: t_subject
        # 绑定表规则列表
        binding-tables[0]: t_student, t_student_subject
        tables:
          t_student:
            actual-data-nodes: ds-$->{0..1}.t_student
            key-generate-strategy:
              column: id
              key-generator-name: snowflake
          t_student_subject:
            actual-data-nodes: ds-$->{0..1}.t_student_subject
            key-generate-strategy:
              column: id
              key-generator-name: snowflake
        key-generators:
          snowflake:
            type: SNOWFLAKE
        sharding-algorithms:
          db-inline:
            type: INLINE
            props:
              algorithm-expression: ds-$->{user_id % 2}
    props:
      sql-show: true
  jpa:
    properties:
      hibernate:
        hbm2ddl:
          auto: update
        dialect: org.hibernate.dialect.MySQL5Dialect
#        show_sql: true
    database: mysql

创建数据库

创建database datas_0, datas_1

drop database if exists datas_0;
drop database if exists datas_1;
create database datas_0;
create database datas_1;

在这里插入图片描述

编写代码

创建对象结构

  • Student: id, name, userId
  • Subject: id, name
  • StudentSubject: id, userId, subjectId
public interface IdObj extends Serializable {

    Long getId();
}
public class Student implements IdObj {

    private Long id;
    private Long userId;
    private String name;

    // ommit getter and setter
}
public class StudentSubject implements IdObj {

    private Long id;
    private Long subjectId;
    private Long userId;

    // ommit getter and setter
}
public class Subject implements IdObj {

    private Long id;
    private String name;

	// ommit getter and setter
}
@Entity
@Table(name = "t_student")
public class StudentEntity extends Student {

    @javax.persistence.Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Override
    public Long getId() {
        return super.getId();
    }

    @Column(name = "user_id")
    @Override
    public Long getUserId() {
        return super.getUserId();
    }
    
    @Column(name = "name")
    @Override
    public String getName() {
        return super.getName();
    }
}
@Entity
@Table(name = "t_student_subject")
public class StudentSubjectEntity extends StudentSubject {

    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Override
    public Long getId() {
        return super.getId();
    }
    @Column(name = "subject_id")
    @Override
    public Long getSubjectId() {
        return super.getSubjectId();
    }

    @Column(name = "user_id")
    @Override
    public Long getUserId() {
        return super.getUserId();
    }
}
@Entity
@Table(name = "t_subject")
public class SubjectEntity extends Subject {

    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Override
    public Long getId() {
        return super.getId();
    }

    @Column(name = "name")
    @Override
    public String getName() {
        return super.getName();
    }
}

创建持久接口

@Repository
public interface StudentRepository extends CrudRepository<StudentEntity, Long> {
}
@Repository
public interface StudentSubjectRepository extends CrudRepository<StudentSubjectEntity, Long> {
}
@Repository
public interface SubjectRepository extends CrudRepository<SubjectEntity, Long> {
}

创建服务类

@Service
public class StudentService {

    @Resource
    StudentRepository studentRepository;

    public void save(StudentEntity studentEntity) {
        studentRepository.save(studentEntity);
    }
}
@Service
public class StudentSubjectService {

    @Resource
    StudentSubjectRepository studentSubjectRepository;

    public void save(StudentSubjectEntity studentSubjectEntity) {
        studentSubjectRepository.save(studentSubjectEntity);
    }
}
@Service
public class SubjectService {

    @Resource
    SubjectRepository subjectRepository;

    public SubjectEntity save(SubjectEntity subjectEntity) {
        return subjectRepository.save(subjectEntity);
    }
}

测试用例

@RunWith(SpringRunner.class)
@SpringBootTest(classes = ShardingSphereMain.class)
@Rollback(value = false)
public class TestApp {

    @Resource
    StudentService studentService;
    @Resource
    StudentSubjectService studentSubjectService;
    @Resource
    SubjectService subjectService;

    public void init() {
        for (long i = 1; i <= 10; i++) {
            StudentEntity studentEntity = new StudentEntity();
            studentEntity.setUserId(i);
            studentService.save(studentEntity);

            SubjectEntity subjectEntity = new SubjectEntity();
            subjectEntity.setName("computer_" + i);
            subjectEntity = subjectService.save(subjectEntity);

            StudentSubjectEntity studentSubjectEntity = new StudentSubjectEntity();
            studentSubjectEntity.setSubjectId(10 + subjectEntity.getId());
            studentSubjectEntity.setUserId(studentEntity.getUserId());
            studentSubjectService.save(studentSubjectEntity);
        }

    }

    @Test
    public void testData() {
        init();
    }
}

执行testcase 生成基础数据

Student 实体类数据会按user_id % 2 的方式入 datas_0, datas_1对应的t_student表中
StudentSubject 实体类数据会按user_id % 2 的方式入 datas_0, datas_1对应的t_student_subject表中
Subject 实体类数据会广播到datas_0, datas_1 对应的t_subject表中

datas_0.t_student

idnameuser_id
802927542603350016named_22
802927542930505728named_44
802927543253467136named_66
802927543551262720named_88
802927543844864000named_1010

datas_0.t_subject

idname
1subject_1
2subject_2
3subject_3
4subject_4
5subject_5
6subject_6
7subject_7
8subject_8
9subject_9
10subject_10

datas_0.t_student_subject

idsubject_iduser_id
802927542720790529122
802927543039557633144
802927543366713345166
802927543664508929188
8029275439539159052010

datas_1.t_student

idnameuser_id
802927541458305024named_11
802927542771122176named_33
802927543085694976named_55
802927543412850688named_77
802927543706451968named_99

datas_1.t_subject

idname
1subject_1
2subject_2
3subject_3
4subject_4
5subject_5
6subject_6
7subject_7
8subject_8
9subject_9
10subject_10

datas_1.t_student_subject

idsubject_iduser_id
802927542532046849111
802927542888562689133
802927543207329793155
802927543513513985177
802927543815503873199

分库分表

分库分表只需对上面的文件稍加改动

application.yml 配置

spring:
  shardingsphere:
    datasource:
      names: ds-0, ds-1
      ds-0:
        type: com.zaxxer.hikari.HikariDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        jdbc-url: jdbc:mysql://192.168.79.177:14306/datas_0?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8
        username: root
        password: 123456
      ds-1:
        type: com.zaxxer.hikari.HikariDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        jdbc-url: jdbc:mysql://192.168.79.177:14306/datas_1?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8
        username: root
        password: 123456
    rules:
      sharding:
        default-database-strategy:
          standard:
            # 以字段分片
            sharding-column: user_id
            # 分片算法名称,可自定义
            sharding-algorithm-name: db-inline
        # 绑定广播表,多库存在此表且数据一致
        broadcast-tables: t_subject
        # 绑定表规则列表
        binding-tables[0]: t_student, t_student_subject
        tables:
          t_student:
            actual-data-nodes: ds-$->{0..1}.t_student
            key-generate-strategy:
              column: id
              key-generator-name: snowflake
          t_student_subject:
            actual-data-nodes: ds-$->{0..1}.t_student_subject
            key-generate-strategy:
              column: id
              key-generator-name: snowflake
        key-generators:
          snowflake:
            type: SNOWFLAKE
        sharding-algorithms:
          db-inline:
            type: INLINE
            props:
              algorithm-expression: ds-$->{user_id % 2}
    props:
      sql-show: true
  jpa:
    properties:
      hibernate:
        hbm2ddl:
          auto: update
        dialect: org.hibernate.dialect.MySQL5Dialect
#        show_sql: true
    database: mysql

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

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

相关文章

气人|这种通过率调优技巧居然这么晚才让我知道

量化风控审核过程中的通过率在贷前策略中是一大重要的内容&#xff0c;另外一个是逾期率。二者之间的因果关系就是通过率高低变化决定了逾期率风险的走势&#xff0c;通过率决定了逾期率的结果&#xff0c;而逾期率又对通过率起到了一个制衡的作用。 很多的风险管理人员常常会遇…

前端实现克里金插值分析(一)

作者:yangjunlin 最近不少小伙伴问我怎么搞前端插值分析&#xff0c;我在github上查找了一些资料&#xff0c;目前最常用的方式是webgis框架idw&#xff08;反距离权重算法&#xff09;d3-contour的方式实现&#xff0c;这种方式是比较简单同时基本能满足一般的气象分析&#x…

Netty入门学习

同步&#xff1a;当调用方法的线程和接收结果的线程是同一个&#xff0c;这意味着阻塞&#xff0c;那么是同步。 异步&#xff1a;当调用方法的线程和处理结果的线程不是同一个&#xff0c;这意味着不是阻塞&#xff0c;是异步。 下图是一个简单的Netty的客户端和服务器端 【…

论文阅读笔记 | 三维目标检测——VoxelNet算法

如有错误&#xff0c;恳请指出。 文章目录1.背景2. 网络结构2.1 体素特征表示2.2 卷积特征提取2.3 RPN网络3. 实验结果paper&#xff1a;《VoxelNet: End-to-End Learning for Point Cloud Based 3D Object Detection》 1.背景 以往的3d检测器都难免利用了手工设计特征(hand-…

ES6 入门教程 29 ArrayBuffer 29.1 ArrayBuffer 对象

ES6 入门教程 ECMAScript 6 入门 作者&#xff1a;阮一峰 本文仅用于学习记录&#xff0c;不存在任何商业用途&#xff0c;如侵删 文章目录ES6 入门教程29 ArrayBuffer29.1 ArrayBuffer 对象29.1.1 概述29.1.2 ArrayBuffer.prototype.byteLength29.1.3 ArrayBuffer.prototype.s…

善网ESG周报(第二期)

ESG报告&#xff1a; 聚焦五大战略&#xff0c;信公股份首次披露ESG报告 近日&#xff0c;信公股份发布首份ESG报告&#xff0c;报告主要涵盖可持续发展战略、高效现代的公司治理、可持续的商业模式与创新、传递社会影响力和守护地球家园等几个维度。 能链智电发布ESG报告&a…

SpringBoot——指标监控,自定义指标监控

为什么要进行指标监控&#xff1f; 在微服务架构中多个组件部署以后&#xff0c;我们需要能够监控到每个组件的健康情况&#xff0c;因此SpringBoot抽取了Actuator用于监控组件。 1.Java自带的监控工具&#xff08;不推荐&#xff09; 步骤&#xff1a; winr输入cmd 回车 进…

广告机联物联卡联网的优势?

广告机联物联卡联网的优势&#xff1f; 随着技术的发展、物联网技术的应用、物联网卡的授权&#xff0c;广告模式也在悄然发生变化&#xff0c;从传统的电视、报纸、杂志等广告模式逐渐转变为建筑之间的广告机。最常见的是地铁、公交车等公共区域设置的广告机或广告屏幕。 一…

67. SAP ABAP 监控用户事物码和程序执行的工具介绍

本文咱们不谈 ABAP 代码编写,而是介绍 SAP ABAP 系统里,如果想查找某个用户在某个时间段之内,在系统干了哪些事情,应该具体如何去做,SAP 又是提供了哪些工具来满足这种监控需求。 本文写作动机来源于一位朋友向我发起的咨询: 我们抛开 SAPGUI Script 这个因素不谈,本文…

第七章《Java的异常处理》第2节:异常的分类及处理方法

异常可以分为多种类型,Java语言允许程序员使用不同的方式来处理不同种类的异常,这样可以实现对异常的精细化处理。 7.2.1异常的分类 7.1小节中提到Exception是用来表示异常的类,但Exception并非Java语言中唯一用来表示异常的类,它只是庞大的异常类家族中的一员。下图7-7就…

[附源码]java毕业设计游戏网站设计

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

第八章 动态规划 5 AcWing 1591. 快速排序

第八章 动态规划 5 AcWing 1591. 快速排序 原题链接 AcWing 1591. 快速排序 算法标签 DP 思路 直接枚举a[i]之前所有元素与a[i]之后所有元素 判断 时间复杂度 O(N2)O(1010)O(N^2)O(10^{10})O(N2)O(1010) 超时 a[i]之前所有元素小于a[i] &#xff0c;即小于a[i]之前所有元…

YOLO算法(You Only Look Once)系列讲解与实现(待完善)

文章目录前言一、指标分析1.mAP (mean Average Precision)2.IOU二、YOLO1.YOLO-v1&#xff08;1&#xff09;步骤&#xff08;2&#xff09;网络结构&#xff08;3&#xff09;损失函数&#xff08;4&#xff09;存在问题2.YOLO-v2&#xff08;1&#xff09;新的尝试-Better&am…

Pod的生命周期

Pod的生命周期 与容器一样&#xff0c;Pod也有生命周期&#xff0c;Pod在整个生命周期中被定义为各种状态。了解这些状态对于后面我们学习Pod的调度是有帮助的。 Pending 挂起状态&#xff0c;Pod已经被K8s系统所认可&#xff0c;但是目前还有一个或多个容器镜像还没有被创建&…

Git错误:Incorrect username or password (access token)

目录 问题描述&#xff1a; 解决办法&#xff1a; 步骤一&#xff1a;进入电脑控制界面 步骤二&#xff1a;进入用户账户 步骤三&#xff1a;管理你的凭据 步骤四&#xff1a;选择Windows凭据 步骤五&#xff1a;找到gitee 步骤六&#xff1a;修改正确的用户名和密码 问…

【学习笔记23】JavaScript数组的遍历方法

笔记首发 1、forEach 语法: 数组.forEach(function(item, index, origin){})参数&#xff1a; item: 数组实际每一项的值index: 数组每一项对应的下标origin:原数组 作用: 遍历数组返回值: 返回值是undefined&#xff0c;哪怕你手写了return&#xff0c;也是undefined var arr…

springboot 使用shiro集成阿里云短信验证码

目录 1.阿里云短信验证码服务 2.发送短信验证码 3.多个realm配置 4.验证短信验证码 5.一些拓展思路 引言&#xff1a;短信验证码是通过发送验证码到手机的一种有效的验证码系统&#xff0c;主要用于验证用户手机的合法性及敏感操作的身份验证。在注册和修改密码时需要用到…

手摸手教会你在idea中配置Tomcat进行servlet/jsp开发(多图超详)

1. 下载安装idea&#xff0c;创建project&#xff0c;如果没有JDK可以通过idea指定文件夹并下载JDK。工程就是普通的Java工程&#xff0c;名字为webdemo 2.因为是Web项目&#xff0c;所以要对这个普通的项目进行WEB扶持^^&#xff0c;在项目名称webdemo上右键单间选择菜单项&qu…

Hive搭建

Hive系列第二章 第二章 Hive搭建 2.1 MySQL5.6安装 1、检查删除已有的 有就删除&#xff0c;没有就不用管。 rpm -qa | grep mysql rpm -e mysql-libs-5.1.73-8.el6_8.x86_64 --nodepsrpm -qa | grep mariadb rpm -e --nodeps mariadb-libs-5.5.56-2.el7.x86_642、删除mysql分…

Windows下Labelimg标注自己的数据集使用(Ubuntu18.04)Jetson AGX Orin进行YOLO5训练测试完整版教程

一、环境配置介绍 整个实现过程所涉及的文件目录&#xff0c;其中&#xff0c;自备表示自己需要准备的&#xff0c;生成表示无需自己准备。 使用yolov5时出现“assertionerror:no labels found in */*/*/JPEGImages.cache can not train without labels”问题 很多朋友都会遇…