Sharding-JDBC(四)集成dynamic-datasource

news2025/7/6 20:26:14

目录

    • 1.Maven依赖
    • 2.yml配置
    • 3.DataSourceConfig.java
    • 4.TUserService.java
    • 5.TUserServiceImpl.java
    • 6.测试代码
    • 7.测试结果
    • 8.源码地址

实现原理:

  • 通过 DataSourceConfig.java 将ShardingJDBC数据源配置为动态数据源之一。
  • 通过 @DS(DataSourceConfig.SHARDING_DATA_SOURCE_NAME) 使用 ShardingJDBC 的数据源进行分表操作。

1.Maven依赖

<!-- Sharding-JDBC -->
<dependency>
    <groupId>org.apache.shardingsphere</groupId>
    <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
    <version>${shardingsphere.version}</version>
</dependency>

<!-- 动态数据源 -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
    <version>3.3.2</version>
</dependency>

2.yml配置

server:
  port: 8081

spring:
  # 多数据源配置
  datasource:
    dynamic:
      primary: mydb1
      datasource:
        mydb1:
          url: jdbc:mysql://localhost:3306/mydb1?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC
          username: root
          password: root
          driver-class-name: com.mysql.cj.jdbc.Driver

  # sharding-jdbc配置
  shardingsphere:
    # 打印sql
    props:
      sql:
        show: true
    datasource:
      names: mydb2
      mydb2:
        type: com.alibaba.druid.pool.DruidDataSource
        url: jdbc:mysql://localhost:3306/mydb2?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
        driver-class-name: com.mysql.cj.jdbc.Driver
        username: root
        password: root
        # 数据源其他配置
        initialSize: 5
        minIdle: 5
        maxActive: 20
        maxWait: 60000
        timeBetweenEvictionRunsMillis: 60000
        minEvictableIdleTimeMillis: 300000
        validationQuery: SELECT 1 FROM DUAL
        testWhileIdle: true
        testOnBorrow: false
        testOnReturn: false
        poolPreparedStatements: true
        # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
        #filters: stat,wall,log4j
        maxPoolPreparedStatementPerConnectionSize: 20
        useGlobalDataSourceStat: true
        connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
    sharding:
      # 表策略配置
      tables:
        # t_user 是逻辑表
        t_user:
          # 分表节点 可以理解为分表后的那些表 比如 t_user_1 ,t_user_2
          actualDataNodes: mydb2.t_user_$->{1..2}
          tableStrategy:
            inline:
              # 根据哪列分表
              shardingColumn: age
              # 分表算法 例如:age为奇数 -> t_user_2; age为偶数 -> t_user_1
              algorithmExpression: t_user_$->{age % 2 + 1}
#              keyGenerator:
#                type: SNOWFLAKE
#                # 对id列采用 sharding-jdbc的全局id生成策略
#                column: id
# mybatis-plus
mybatis-plus:
  mapper-locations: classpath*:/mapper/*Mapper.xml
  # 实体扫描,多个package用逗号或者分号分隔
  typeAliasesPackage: cn.agile.stats.*.entity
  # 测试环境打印sql
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

3.DataSourceConfig.java

DataSourceConfig作用: 将ShardingJDBC数据源配置为动态数据源之一。

import com.baomidou.dynamic.datasource.DynamicRoutingDataSource;
import com.baomidou.dynamic.datasource.provider.AbstractDataSourceProvider;
import com.baomidou.dynamic.datasource.provider.DynamicDataSourceProvider;
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DataSourceProperty;
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceAutoConfiguration;
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceProperties;
import org.apache.shardingsphere.shardingjdbc.jdbc.adapter.AbstractDataSourceAdapter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Primary;

import javax.annotation.Resource;
import javax.sql.DataSource;
import java.util.Map;

/**
 * <p> @Title DataSourceConfig
 * <p> @Description 动态数据源配置(切换为sharding-jdbc数据源 => @DS(DataSourceConfig.SHARDING_DATA_SOURCE_NAME))
 *
 * @author ACGkaka
 * @date 2022/12/21 16:01
 */
@Configuration
@AutoConfigureBefore({DynamicDataSourceAutoConfiguration.class, SpringBootConfiguration.class})
public class DataSourceConfig {
    /**
     * 分表数据源名称
     */
    public static final String SHARDING_DATA_SOURCE_NAME = "sharding-data-source";
    /**
     * 动态数据源配置项
     */
    @Autowired
    private DynamicDataSourceProperties properties;

    /**
     * sharding-jdbc有四种数据源,需要根据业务注入不同的数据源
     * <p>
     * 1.未使用分片, 脱敏的名称(默认): shardingDataSource;
     * 2.主从数据源: masterSlaveDataSource;
     * 3.脱敏数据源:encryptDataSource;
     * 4.影子数据源:shadowDataSource
     */
    @Lazy
    @Resource(name = "shardingDataSource")
    private AbstractDataSourceAdapter shardingDataSource;

    @Bean
    public DynamicDataSourceProvider dynamicDataSourceProvider() {
        Map<String, DataSourceProperty> datasourceMap = properties.getDatasource();
        return new AbstractDataSourceProvider() {
            @Override
            public Map<String, DataSource> loadDataSources() {
                Map<String, DataSource> dataSourceMap = createDataSourceMap(datasourceMap);
                // 将 shardingjdbc 管理的数据源也交给动态数据源管理
                dataSourceMap.put(SHARDING_DATA_SOURCE_NAME, shardingDataSource);
                return dataSourceMap;
            }
        };
    }

    /**
     * 将动态数据源设置为首选的
     * 当spring存在多个数据源时, 自动注入的是首选的对象
     * 设置为主要的数据源之后,就可以支持sharding-jdbc原生的配置方式了
     */
    @Primary
    @Bean
    public DataSource dataSource(DynamicDataSourceProvider dynamicDataSourceProvider) {
        DynamicRoutingDataSource dataSource = new DynamicRoutingDataSource();
        dataSource.setPrimary(properties.getPrimary());
        dataSource.setStrict(properties.getStrict());
        dataSource.setStrategy(properties.getStrategy());
        dataSource.setProvider(dynamicDataSourceProvider);
        dataSource.setP6spy(properties.getP6spy());
        dataSource.setSeata(properties.getSeata());
        return dataSource;
    }
}

4.TUserService.java

import com.demo.module.entity.TUser;
import com.baomidou.mybatisplus.extension.service.IService;

import java.util.List;

/**
 * <p>
 * 用户表 服务类
 * </p>
 *
 * @author ACGkaka
 * @since 2021-04-25
 */
public interface TUserService extends IService<TUser> {

    /**
     * 查询 全部用户(mydb1数据库)
     * @return 全部用户
     */
    List<TUser> listFromDB1();
}

5.TUserServiceImpl.java

import com.baomidou.dynamic.datasource.annotation.DS;
import com.demo.module.config.DataSourceConfig;
import com.demo.module.entity.TUser;
import com.demo.module.mapper.TUserMapper;
import com.demo.module.service.TUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * <p>
 * 用户表 服务实现类
 * </p>
 *
 * @author ACGkaka
 * @since 2021-04-25
 */
@Service
@DS(DataSourceConfig.SHARDING_DATA_SOURCE_NAME)
public class TUserServiceImpl extends ServiceImpl<TUserMapper, TUser> implements TUserService {

    @DS("mydb1")
    @Override
    public List<TUser> listFromDB1() {
        // 查询 全部用户(mydb1数据库)
        return this.list();
    }
}

6.测试代码

@Test
void saveTest() {
    List<TUser> users = new ArrayList<>(3);
    users.add(new TUser("ACGkaka_1", "123456", 10));
    users.add(new TUser("ACGkaka_2", "123456", 11));
    users.add(new TUser("ACGkaka_3", "123456", 12));
    userService.saveBatch(users);
}

@Test
void listTest() {
    List<TUser> users1 = userService.listFromDB1();
    System.out.println(">>>>>>>>>> 【Result1】<<<<<<<<<< ");
    users1.forEach(System.out::println);
    List<TUser> users2 = userService.list();
    System.out.println(">>>>>>>>>> 【Result2】<<<<<<<<<< ");
    users2.forEach(System.out::println);
}

7.测试结果

查询没有数据插入的mydb1,没有查到数据:

在这里插入图片描述

查询插入了 3 条数据的mydb2,查询到了 3 条:

请添加图片描述

测试成功,数据根据动态数据源配置实现了对 mydb1 和 mydb2 两个数据库的操作。

8.源码地址

地址: https://gitee.com/acgkaka/SpringBootExamples/tree/master/springboot-sharding-jdbc-dynamic

整理完毕,完结撒花~





参考地址:

1.SpringBoot(50) 整合sharding-jdbc和多数据源,https://blog.csdn.net/qq_38225558/article/details/121107962

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

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

相关文章

Coinbase Vntures:Web3社交堆栈指南

概述 Web3社交网络赋予用户对其数据、身份和关系的所有权及可移植性&#xff0c;同时支持无需许可的开发。 Web3社交堆栈有四层&#xff1a;托管、社交原语、profile和应用程序。 例如&#xff1a;Farcaster是一款类似twitter的社交应用程序&#xff0c;它创建在开放的社交图…

HTTPS协议的密钥交换流程

前言 HTTPS 常用的密钥交换算法有两种&#xff0c;分别是 RSA 和 ECDHE 算法。 其中&#xff0c;RSA 是比较传统的密钥交换算法&#xff0c;它不具备前向安全的性质&#xff0c;因此现在已很少服务器使用。而 ECDHE 算法具有前向安全&#xff0c;所以被广泛使用。 注&#xf…

18 | 如何处理k8s证书过期

目录1 证书过期2 常用命令2.1 使用统一命令查看2.2 查看apiserver.crt证书时间2.3 查看secret2.4 查看ingress3 k8s证书过期处理方法1 证书过期 证书在使用的过程中&#xff0c;通常是一年有效期&#xff0c;到期后&#xff0c;需要重新续期。 2 常用命令 2.1 使用统一命令查…

智慧车行预约小程序,汽车保养、维修、美容、检测预测小程序,前后端完整代码包括车行动态,养车常识,保养预约,维修预约,洗车美容预约

功能介绍 智慧车行小程序&#xff0c;是一个专门为洗车/4S/车辆维修行业打造的小程序&#xff0c;前后端完整代码包括车行动态&#xff0c;养车常识&#xff0c;保养预约&#xff0c;维修预约&#xff0c;洗车美容预约&#xff0c;汽车检测预约等功能&#xff0c;采用腾讯提供的…

分布式锁

目录 1. 模拟高并发场景秒杀下单 1.1 导入依赖 1.2 配置application.yml文件 1.3 场景模拟 1.4 案例演示 2. JVM级锁与redis级分布式锁 2.1 JVM级锁 3. redis级分布式锁 3.1 什么是setnx 3.2 场景分析 4. redisson分布式锁 4.1 什么是Redisson 4.2 Redisson工作原…

有关于decoder中的past_key_values参数

我们都知道&#xff0c;encoder-decoder模型在进行generate的时候&#xff0c;会重复地调用decoder &#xff08;i.e., auto-regressive&#xff09;。 也就是&#xff0c;上一个step decoder的预测结果&#xff0c;作为下一个step decoder的输入。 这个时候&#xff0c;由于…

Axios(一) +Promise自定义封装36-42

1. axios 是什么? 1. 前端最流行的 ajax 请求库 2. react/vue 官方都推荐使用 axios 发 ajax 请求 3. 文档: https://github.com/axios/axios 1.2. axios 特点 1. 基于 xhr promise 的异步 ajax 请求库 2. 浏览器端/node 端都可以使用 3. 支持请求&#xff0f;响应拦截器 4…

从零开始,开启属于你的 RTE 漫游之旅!丨漫游指南 x 即将启航

&#x1f914; 什么是「开发者漫游指南」&#xff1f; 「开发者漫游指南」邀请热爱前端开发、关心音视频领域发展、希望进入音视频行业、乐于和大家一起交流成长的小伙伴&#xff0c;通过「开发者漫游指南」与社区共同成长&#xff0c;帮助更多的开发者在实时音视频领域取得进…

Linux中gdb的使用

文章目录gdb的使用方法启动gdb之前的准备工作下载gdb拥有一个带有调试信息的可执行程序正式启动gdb展示源码&#xff08;要先看到源码才知道接下来的步骤……&#xff09;打断点显示所有断点信息运行程序逐过程&#xff08;VS中的F10&#xff09;逐语句&#xff08;VS中的F11&a…

实验四、格子世界(Grid World)

一、实验目的 &#xff08;1&#xff09;熟悉动态规划算法中策略评估过程&#xff1b; &#xff08;2&#xff09;了解如何对问题进行建模处理&#xff0c;包括环境、状态、动作、奖惩值的初始化&#xff1b; 二、实验内容与要求 &#xff08;1&#xff09;掌握动态算法基本…

华为机试_HJ27 查找兄弟单词【中等】

目录 描述 输入描述&#xff1a; 输出描述&#xff1a; 解题过程 提交代码 学习代码 代码一 收藏点 描述 定义一个单词的“兄弟单词”为&#xff1a;交换该单词字母顺序&#xff08;注&#xff1a;可以交换任意次&#xff09;&#xff0c;而不添加、删除、修改原有的字…

Linux系统 PHP安装expect扩展详解

今天继续给大家介绍服务器运维相关知识&#xff0c;本文主要内容是Linux系统 PHP安装expect扩展详解。 一、expect简介 expect是基于tcl语言开发的&#xff0c;用于实现自动和交互式任务进行通信&#xff0c;而无须人的干预。expect是建立在tcl基础上的一个工具&#xff0c;还…

Navicat--对比和同步MySQL表结构的方法

原文网址&#xff1a;Navicat--对比和同步MySQL表结构的方法_IT利刃出鞘的博客-CSDN博客 简介 本文介绍如何使用Navicat对比和同步MySQL表结构的方法。 实际项目中会遇到这样的场景&#xff1a;将测试环境的表结构同步到生产环境。 工具> 结构同步 选择源数据库和目标数据…

tensorflow 基本概念和基本操作

op和tensor之间的关系 op是graph上的节点&#xff0c;线就是tensor。 op输入tensor&#xff0c;同时也产出下游的tensor 作为每一个tensor&#xff0c;都会有一个op的属性(attribute)&#xff0c;该op就代表着这个tensor是被什么计算产出的。举个例子&#xff1a; In [74]: w…

Redis6 主从复制

Redis6 主从复制1. 什么是主从复制2. 能做什么3. 配置1主2从3.1 配置3.2 启动redis3.3 配置主从关系4.常见问题4.1 一主二仆5. 主从复制原理6. 薪火相传7. 反客为主1. 什么是主从复制 主机数据更新后根据配置和策略&#xff0c; 自动同步到备机的master/slaver机制&#xff0c…

C++--数据结构--最短路径--Dijkstra--Bellman-Ford算法--Floyd-Warshall算法--高阶0713 14

注&#xff1a;本篇所用的某些未在本文中实现的函数&#xff0c;或不明确的类&#xff0c;均在上篇博客中有详细过程&#xff0c;因篇幅问题不再赘述。 C--数据结构--图的相关概念及模拟实现--高阶0712_Gaze&#xff01;的博客-CSDN博客 1. Dijkstra算法 Dijkstra算法需要开辟…

spring-boot 接收form表单 多文件加多字段数据(postman在form-data格式下传数组和集合)

前言 该博客多用于记录自己的问题 在写项目的时候遇到这种业务情况&#xff1a; 需要保存整个页面的数据&#xff0c;数据包含多个字段信息和多个文件 结合网上的处理思路&#xff0c;我最终实现了这种业务需求并整理一下 前端单独提交字段和文件比较方便简单&#xff0c;本人…

带你读AI论文丨针对文字识别的多模态半监督方法

摘要&#xff1a;本文提出了一种针对文字识别的多模态半监督方法&#xff0c;具体来说&#xff0c;作者首先使用teacher-student网络进行半监督学习&#xff0c;然后在视觉、语义以及视觉和语义的融合特征上&#xff0c;都进行了一致性约束。本文分享自华为云社区《一种针对文字…

构建高性能内存队列:Disruptor

1、 背景 Java中有哪些队列 ArrayBlockingQueue 使用ReentrantLock LinkedBlockingQueue 使用ReentrantLock ConcurrentLinkedQueue 使用CAS 等等 我们清楚使用锁的性能比较低&#xff0c;尽量使用无锁设计。接下来就我们来认识下Disruptor。 2、Disruptor简单使用 github地…

Web3中文|可判115年监禁的FTX创始人SBF即将被引渡到美国

巴哈马总检察长办公室在宣布逮捕FTX前CEO Sam Bankman-Fried时&#xff0c;指出他很可能应美国要求被引渡。 一个多星期后&#xff0c;美国广播公司新闻报道称 &#xff0c;SBF于12月20日签署了引渡文件。 另据彭博社12月20日的一份报告称&#xff0c;该交易所创始人SBF于12月…