Spring Boot集成ShardingSphere配合dynamic-datasource进行数据源切换 | Spring Cloud 49

news2024/11/29 20:48:36

一、前言

通过以下系列章节:

Spring Boot集成ShardingSphere实现数据分片(一) | Spring Cloud 40

Spring Boot集成ShardingSphere实现数据分片(二) | Spring Cloud 41

Spring Boot集成ShardingSphere实现数据分片(三) | Spring Cloud 42

Spring Boot集成ShardingSphere实现读写分离 | Spring Cloud 43

Spring Boot集成ShardingSphere实现按月数据分片及创建自定义分片算法 | Spring Cloud 44

Spring Boot集成ShardingSphere分片利器 AutoTable (一)—— 简单体验 | Spring Cloud 45

Spring Boot集成ShardingSphere分片利器 AutoTable (二)—— 自动分片算法示例 | Spring Cloud 46

ShardingSphere 5.3 系列Spring 配置升级指南 | Spring Cloud 47

Spring Boot集成ShardingSphere实现数据加密及数据脱敏 | Spring Cloud 48

ShardingSphere的数据分片、各分片算法应用、读写分离、数据加密、数据脱敏、最新版本升级等情况有了详细的了解,今天我们继续对其与dynamic-datasource集成实现多数据源进行演示学习。

本章节中会应用以上系列章节的部分示例,shardingsphere-jdbc-core版本为5.3.x版本
阅读本章前建议先阅读:ShardingSphere 5.3 系列Spring 配置升级指南 | Spring Cloud 47

二、背景

可能存在以下场景:原项目中使用的是dynamic-datasource进行数据源管理,由于项目经历一段时间的线上运行,数据库压力越来越大,计划使用shardingsphere-jdbc进行数据分片或读写分离。

2.1 dynamic-datasource介绍

dynamic-datasource-spring-boot-starter 是一个基于springboot的快速集成多数据源的启动器。

dynamic-datasource官方文档:https://www.kancloud.cn/tracy5546/dynamic-datasource/2264611

2.1.1 特征

  • 支持 数据源分组 ,适用于多种场景 纯粹多库 读写分离 一主多从 混合模式。
  • 支持数据库敏感配置信息加密 ENC()
  • 支持每个数据库独立初始化表结构schema和数据库database
  • 支持无数据源启动,支持懒加载数据源(需要的时候再创建连接)。
  • 支持 自定义注解 ,需继承DS(3.2.0+)
  • 提供并简化对DruidHikariCpBeeCpDbcp2的快速集成。
  • 提供对Mybatis-PlusQuartzShardingJdbcP6syJndi等组件的集成方案。
  • 提供 自定义数据源来源 方案(如全从数据库加载)。
  • 提供项目启动后 动态增加移除数据源 方案。
  • 提供Mybatis环境下的 纯读写分离 方案。
  • 提供使用 spel动态参数 解析数据源方案。内置spelsessionheader,支持自定义。
  • 支持 多层数据源嵌套切换 。(ServiceA >>> ServiceB >>> ServiceC)。
  • 提供 基于seata的分布式事务 方案。
  • 提供 本地多数据源事务 方案。 附:不能和原生spring事务混用。

2.1.2 约定

  • 框架只做 切换数据源 这件核心的事情,并不限制你的具体操作,切换了数据源可以做任何CRUD
  • 配置文件所有以下划线 _ 分割的数据源 首部 即为组的名称,相同组名称的数据源会放在一个组下。
  • 切换数据源可以是组名,也可以是具体数据源名称组名则切换时采用负载均衡算法切换
  • 默认的数据源名称为 master ,你可以通过 spring.datasource.dynamic.primary 修改。
  • 方法上的注解优先于类上注解
  • DS支持继承抽象类上的DS,暂不支持继承接口上的DS

三、使用示例

示例采用springboot集成shardingsphere-jdbc方式搭建。

3.1 项目总体结构

在这里插入图片描述

3.2 Maven依赖

shading-sphere/shading-dynamic-datasource/pom.xml

<?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">
    <parent>
        <artifactId>shading-sphere</artifactId>
        <groupId>com.gm</groupId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>shading-dynamic-datasource</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--<dependency>
            <groupId>org.apache.shardingsphere</groupId>
            <artifactId>shardingsphere-jdbc-core-spring-boot-starter</artifactId>
            <version>5.2.1</version>
        </dependency>-->

        <dependency>
            <groupId>org.apache.shardingsphere</groupId>
            <artifactId>shardingsphere-jdbc-core</artifactId>
            <version>5.3.2</version>
        </dependency>

        <!-- 解决Mybatis中LocalDateTime和SQL中datetime的交互 -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-typehandlers-jsr310</artifactId>
            <version>1.0.2</version>
        </dependency>

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.3.1</version>
        </dependency>

        <dependency>
            <groupId>org.yaml</groupId>
            <artifactId>snakeyaml</artifactId>
            <version>1.33</version>
        </dependency>

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
            <version>3.6.1</version>
        </dependency>
    </dependencies>
</project>
  • shardingsphere-jdbc-core使用最新的5.3.2版本
  • dynamic-datasource-spring-boot-starter使用最新的3.6.1版本
  • mybatis-plus-boot-starter使用最新的3.5.3.1版本

3.3 配置文件

src/main/resources/application.yml

server:
  port: 8844

spring:
  application:
    name: @artifactId@
  datasource:
    dynamic:
      primary: master_1 # 设置默认的数据源或者数据源组,默认值即为master
      strict: false # 严格匹配数据源,默认false. true未匹配到指定数据源时抛异常,false使用默认数据源
      datasource:
        master_1:
          driver-class-name: com.mysql.cj.jdbc.Driver
          url: jdbc:mysql://192.168.0.35:3306/seata-demo-consumer?useUnicode=true&characterEncoding=UTF-8&rewriteBatchedStatements=true&allowMultiQueries=true&serverTimezone=Asia/Shanghai
          username: root
          password: '1qaz@WSX'
        master_2:
          driver-class-name: org.apache.shardingsphere.driver.ShardingSphereDriver
          url: jdbc:shardingsphere:classpath:shading-auto-tables-algorithm.yaml
mybatis:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

配置简要说明:
dynamic-datasource多数据源配置,其中数据源master_2基于 ShardingSphereDriver 配置项加载shardingsphere数据源及分片规则

src/main/resources/shading-auto-tables-algorithm.yaml

dataSources:
  ds1:
    dataSourceClassName: com.zaxxer.hikari.HikariDataSource
    driverClassName: com.mysql.cj.jdbc.Driver
    jdbcUrl: jdbc:mysql://192.168.0.35:3306/db1?useUnicode=true&characterEncoding=UTF-8&rewriteBatchedStatements=true&allowMultiQueries=true&serverTimezone=Asia/Shanghai
    username: root
    password: '1qaz@WSX'
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 50
    minPoolSize: 1

  ds2:
    dataSourceClassName: com.zaxxer.hikari.HikariDataSource
    driverClassName: com.mysql.cj.jdbc.Driver
    jdbcUrl: jdbc:mysql://192.168.0.46:3306/db2?useUnicode=true&characterEncoding=UTF-8&rewriteBatchedStatements=true&allowMultiQueries=true&serverTimezone=Asia/Shanghai
    username: root
    password: '1qaz@WSX'
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 50
    minPoolSize: 1
rules:
  - !SHARDING
    autoTables:
      # 取模
      t_auto_order_mod:
        actualDataSources: ds$->{1..2}
        shardingStrategy:
          standard:
            shardingColumn: order_id
            shardingAlgorithmName: auto_order_mod
        # 分布式序列策略
        keyGenerateStrategy:
          # 自增列名称,缺省表示不使用自增主键生成器
          column: order_id
          # 分布式序列算法名称
          keyGeneratorName: snowflake
    # 分片算法配置
    shardingAlgorithms:
      # 取模
      auto_order_mod:
        type: MOD
        props:
          sharding-count: 6
    # 分布式序列算法配置(如果是自动生成的,在插入数据的sql中就不要传id,null也不行,直接插入字段中就不要有主键的字段)
    keyGenerators:
      # 分布式序列算法名称
      snowflake:
        # 分布式序列算法类型
        type: SNOWFLAKE
props:
  sql-show: true

配置简要说明:
逻辑表 t_auto_order_mod按照order_id分片键使用MOD自动分片算法进行分片

3.4 实体类

com/gm/shading/dynamic/datasource/entity/AutoOrderMod.java

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.math.BigDecimal;

@Data
@TableName("t_auto_order_mod")
public class AutoOrderMod {

    @TableId(type = IdType.ASSIGN_ID)
    private Long orderId;
    private BigDecimal price;
    private Long userId;
    private String status;
}

3.5 Mapper

com/gm/shading/dynamic/datasource/mapper/AutoOrderModMapper.java

import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.gm.shading.dynamic.datasource.entity.AutoOrderMod;
import org.apache.ibatis.annotations.Mapper;

@DS("master_2")
@Mapper
public interface AutoOrderModMapper extends BaseMapper<AutoOrderMod> {
    void save(AutoOrderMod autoOrder);
}

通过注解@DS方式制定使用数据源master_2

src/main/resources/mapper/AutoOrderModMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.gm.shading.dynamic.datasource.mapper.AutoOrderModMapper">
    <insert id="save" parameterType="com.gm.shading.dynamic.datasource.entity.AutoOrderMod">
        insert into t_auto_order_mod (price, user_id, status)
        values (#{price}, #{userId}, #{status})
    </insert>
</mapper>

3.6 启动类

com/gm/shading/dynamic/datasource/ShadingDynamicDatasourceApplication.java

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@MapperScan("com.gm.shading.dynamic.datasource.mapper")
public class ShadingDynamicDatasourceApplication {
    public static void main(String[] args) {
        SpringApplication.run(ShadingDynamicDatasourceApplication.class, args);
    }
}

3.7 单元测试

src/test/java/com/gm/shading/dynamic/datasource/ShadingDynamicDatasourceApplicationTests.java

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.gm.shading.dynamic.datasource.entity.AutoOrderMod;
import com.gm.shading.dynamic.datasource.mapper.AutoOrderModMapper;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.jdbc.core.JdbcTemplate;
import java.math.BigDecimal;
import java.util.List;
import java.util.Random;

@SpringBootTest
@Slf4j
public class ShadingDynamicDatasourceApplicationTests {
    
    @Autowired
    AutoOrderModMapper autoOrderModMapper;

    @Autowired
    JdbcTemplate jdbcTemplate;

    @Test
    public void testCreateAutoOrderMod() {
        jdbcTemplate.execute("CREATE TABLE `t_auto_order_mod` (\n" +
                " `order_id` bigint(20) NOT NULL COMMENT '订单id',\n" +
                " `price` decimal(10,2) NOT NULL COMMENT '订单价格',\n" +
                " `user_id` bigint(20) NOT NULL COMMENT '下单用户id',\n" +
                " `status` varchar(50) NOT NULL COMMENT '订单状态',\n" +
                " PRIMARY KEY (`order_id`) USING BTREE\n" +
                ") ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;");
    }

    @Test
    public void testInsertAutoOrderMod() {
        Random random = new Random();
        for (int i = 1; i < 10; i++) {
            AutoOrderMod order = new AutoOrderMod();
            order.setPrice(new BigDecimal(i));
            order.setUserId(Integer.valueOf(random.nextInt(25)).longValue());
            order.setStatus(i + "");
            autoOrderModMapper.save(order);
        }
    }

    @Test
    public void testSelectAutoOrderMod() {
        List<AutoOrderMod> list = autoOrderModMapper.selectList(new QueryWrapper<AutoOrderMod>());
        for (AutoOrderMod autoordermod : list) {
            log.info("{}", autoordermod);
        }
    }
}
  • 执行testCreateAutoOrderMod方法根据自动配置的分片规则进行建表
  • 执行testInsertAutoOrderMod方法完成数据插入
  • 执行testSelectAutoOrderMod方法完成数据查询

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

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

相关文章

沉痛悼念互联网[云原生领域]技术大牛----左耳朵耗子(陈皓老师)

陈皓老师&#xff0c;网名"左耳朵耗子"&#xff0c;是一位在互联网界享有盛誉的伟大人物。他的一生充满了创造力、智慧和奉献精神&#xff0c;对技术领域做出了卓越的贡献。 陈皓老师 为什么网名叫 左耳朵耗子? 陈皓老师之所以取名"左耳朵耗子"&#xff…

HDMI接口说明

目录 一、概述 二、信号说明 三、信号定义 四、握手过程 五、调试步骤 一、概述 HDMI ,High-Definition Multimedia Interface,即高清晰度多媒体接口&#xff0c;是电脑、电视等相关显示设备的接口。 二、信号说明 HDMI分为Source,Sink.Source即信号源&#xff0c;为HDMI…

网络基础协议

1、网络协议/TCP/UDP/HTTP 网络协议是指在计算机网络中&#xff0c;不同设备之间进行通信时所使用的规则、约定和标准。常见的网络协议包括TCP协议、UDP协议、HTTP协议等。 TCP协议是一种面向连接、可靠的传输层协议&#xff0c;它提供了可靠的数据传输和数据包检错能力。在网…

新星计划2023【网络应用领域基础】——————Day3

常见的网络基础介绍 前言 我们系数了网络发展的历史和一些常见的协议&#xff0c;以下文章我将详细的讲网络层协议以及用拓扑来解释单臂路由和vlan的划分。结尾将会额外的额解释常见的抓包。 目录 常见的网络基础介绍​ 前言 我们系数了网络发展的历史和一些常见的协议&…

蓝桥杯拿到一等奖,并分享经验

昨天和群里的小伙伴在群里聊&#xff0c;有的小伙伴竟然说蓝桥杯一等奖没有含量&#xff0c;我也是醉了&#xff01; 就像去年看了一个号主写的&#xff1a;研究生遍地都是! 放眼全国14亿人口&#xff0c;别说研究生了&#xff0c;本科生占比有多少? “蓝桥杯是我人生中得到…

移动硬盘中剪切的文件能恢复吗?可尝试这四种方法找回

在使用移动硬盘时&#xff0c;我们所存储的数据很容易出现意外丢失、被删除、受到病毒感染等方方面面的问题。而如果你使用的是剪切操作&#xff0c;而不是复制操作来移动文件&#xff0c;那么在操作过程中很容易因为各种原因导致数据丢失。如果你遇到了这种情况&#xff0c;那…

持续熬夜爆肝,炸裂的OPEN AI 快速开发平台后台管理同步上线啦 ,完全免费聊天主题也即将上线

持续几天几夜晚&#xff0c;不眠不休的项目开发&#xff0c;终于完成第一版整 OPEN AI 快速开发平台API 和大家见面了&#xff0c;这次包含后台管理&#xff0c;用户开发者入住&#xff0c;和完整的接口文档 OPEN AI快速开发平台这里进入 连接上一篇文章 爆肝一周&#xff0…

【JAVA程序设计】(C00134)基于SSM(非maven)的在线餐饮管理系统

基于SSM&#xff08;非maven&#xff09;的在线餐饮管理系统 项目简介项目获取开发环境项目技术运行截图 项目简介 ssm在线餐饮管理系统 本项目包含管理员与普通用户两种角色&#xff1b; 管理员角色包含以下功能&#xff1a; 管理员登录,查看销售报表,餐桌管理,菜式管理,菜品…

【新星计划】数据库 CTE 初识

【新星计划】数据库 CTE 初识 CTECTE 语法 CTE 递归CTE 递归语法递归示例递归机制 几个CTE 递归的示例阶乘斐波那契序列无限级分类路径 rand 函数小结 CTE CTE指的是公共表表达式(Common Table Expression) 在日常我们使用数据库的时候&#xff0c;通常在一些数据汇总计算的时候…

京东商品详情数据接口采集技术,支持整站数据高并发采集

一、如何通过手动方式查看京东商品详情页面的数据 1.京东商品详情 API 接口&#xff08;item_get - 获得京东商品详情接口&#xff09;&#xff0c;京东API 接口代码对接可以获取到宝贝 ID&#xff0c;宝贝标题&#xff0c;价格&#xff0c;优惠价&#xff0c;掌柜名称&…

节卡率先冲刺科创板,协作机器人商业化正当时

日前&#xff0c;上交所新增受理节卡机器人股份有限公司科创板上市申请&#xff0c;该公司拟募集资金7.5亿元&#xff0c;国泰君安任保荐人。此前&#xff0c;节卡机器人共完成6轮融资&#xff0c;总融资额超14亿元。按照最后的一轮融资计算&#xff0c;公司引入软银愿景基金二…

如何在云上部署java项目

最近博主接了一波私活&#xff0c;由于上云的概念已经深入人心&#xff0c;客户要求博主也上云&#xff0c;本文将介绍上云的教程。 1.如何选择服务器 这里博主推荐阿里云服务器&#xff0c;阿里云云服务器ECS是一种安全可靠、弹性可伸缩的云计算服务&#xff0c;助您降低 IT…

缓存三种方式

缓存能解决的问题 提升性能 绝大多数情况下&#xff0c;select 是出现性能问题最大的地方。一方面&#xff0c;select 会有很多像 join、group、order、like 等这样丰富的语义&#xff0c;而这些语义是非常耗性能的&#xff1b;另一方面&#xff0c;大多 数应用都是读多写少&…

阿里出版的这份Spring Security源码手册,狂揽GitHub榜首

写在前面 自从 Spring Boot、Spring Cloud 火起来之后&#xff0c;Spring Security 也跟着沾了一把光&#xff01; 其实我一直觉得 Spring Security 是一个比 Shiro 优秀很多的权限管理框架&#xff0c;但是重量级、配置繁琐、门槛高这些问题一直困扰着 Spring Security 的开…

【保姆级教程】如何用Rust编写一个ChatGPT桌面应用 | 京东云技术团队

为什么我们需要一个桌面应用 原因实在太多&#xff0c;我们需要便捷地导出记录&#xff0c;需要在回答长度超长的时候自动加上“继续”&#xff0c;需要收藏一些很酷很实用的prompt… &#xff08;首先我假设你是一名如我一样习惯用IDEA开发的java仔&#xff09; 为什么是用R…

孙鑫VC++第四章 1.简单绘图-MFC消息映射机制

1. MFC消息映射机制 接下来将剖析MFC消息映射机制&#xff0c;探讨发送给窗口的消息是如何被MFC框架通过窗口句柄映射表和消息映射表来用窗口类的处理函数进行响应的。另外&#xff0c;还将讲述“类向导”这一工具的运用&#xff0c;讨论设备描述表及其封装类CDC的使用&#x…

Javase06|类和对象

Javase06|类和对象 文章目录 Javase06|类和对象1.面向对象的初步认识2.类的定义3.类的实例化4.this引用5.对象的构造及初始化6.封装7.static成员8.代码块 1.面向对象的初步认识 1.1对象的概念 Java是一门面向对象的语言&#xff0c;面向对象主要依靠对象之间的交互完成一件事…

审稿意见相互矛盾的11种可能情况及修改建议

遇到相互矛盾的审稿意见&#xff0c;作者很难不纠结&#xff0c;毕竟哪个审稿人都不想得罪&#xff0c;到底该怎么办呢&#xff1f; 虽然有些审稿意见乍一看上去相互矛盾&#xff0c;但深思之后&#xff0c;也能发现其中的共性或者根本问题。明确了这一点&#xff0c;就比较清楚…

<六> objectARX开发:创建、插入、删除图块

1、介绍 所有的实体都保存在块表记录中,而块表记录则存储在块表中。实际上,用户在AutoCAD中定义块相当于增加了一个块表记录,块表记录的名称就是块定义的名称。打开任意dwg文件,然后创建两个从图中可以看出,当前图形的块表中包含了五个记录: *Model_Space、 Paper_Space、…

Qt--基于TCP客户端与服务器的聊天程序(半双工通信)

目录 任务&#xff1a;实现一个基于TCP的聊天程序&#xff0c;需要使用的类有&#xff1a; QTcpServer ​编辑 QTcpSocket ​编辑 QTextStream 服务端&#xff1a;server&#xff08;QTcpServer&#xff09; 步骤&#xff1a; 代码&#xff1a; dialog.h dialog.cpp 客户端&am…