springboot项目实现分库

news2024/9/21 2:21:52

本文是根据仓库编码 和 仓库id进行按仓库进行分库处理,可以根据例子自行按照业务需要进行分库

1.核心是实现 Spring 的 AbstractRoutingDataSource 抽象类,重写 determineCurrentLookupKey 方法,实现动态数据源的目的

@Slf4j
public class DynamicDataSource extends AbstractRoutingDataSource {


    /**
     * ThreadLocal 线程独立存储
     */
    private static final ThreadLocal<String> THREAD_HOLD_SOURCE = new InheritableThreadLocal<>();

    /**
     * 决定使用哪个数据源之前需要把多个数据源的信息以及默认数据源信息配置好
     *
     * @param defaultTargetDataSource 默认数据源
     * @param targetDataSources       目标数据源
     */
    public DynamicDataSource(DataSource defaultDataSource, Map<Object, Object> targetDataSources) {
        super.setDefaultTargetDataSource(defaultDataSource);
        super.setTargetDataSources(targetDataSources);
        super.afterPropertiesSet();
    }

    /**
     * 如果不希望数据源在启动配置时就加载好,可以定制这个方法,从任何你希望的地方读取并返回数据源
     * 比如从数据库、文件、外部接口等读取数据源信息,并最终返回一个DataSource实现类对象即可
     */
    @Override
    protected DataSource determineTargetDataSource() {
        return super.determineTargetDataSource();
    }


    /**
     * 如果希望所有数据源在启动配置时就加载好,这里通过设置数据源Key值来切换数据,定制这个方法
     *
     * @return
     */
    @Override
    protected Object determineCurrentLookupKey() {
        return getDataSource();
    }

    /**
     * 通过同一线程获取对应
     */
    public static String getDataSource() {
        log.info("获取选择对应的数据源名称:{}", THREAD_HOLD_SOURCE.get());
        return THREAD_HOLD_SOURCE.get();
    }

    public static void setDataSource(String sourceName) {
        log.info("设置对应的数据源名称:{}", sourceName);
        THREAD_HOLD_SOURCE.set(sourceName);
    }

    public static void clearDataSource() {
        THREAD_HOLD_SOURCE.remove();
    }

}

2.springboot项目启动类同级配置动态数据源配置

@Configuration
public class DynamicDataSourceConfig {




    /**
     * 数据源01 默认数据源
     */
    @Bean(name = DataSourceConst.test_01)
    @ConfigurationProperties("spring.datasource.test01")
    public DataSource test01() {
        return DruidDataSourceBuilder.create().build();
    }

    /**
     * 数据源02
     */
    @Bean(name = DataSourceConst.test_02)
    @ConfigurationProperties("spring.datasource.test02")
    public DataSource test02() {
        return DruidDataSourceBuilder.create().build();
    }

    /**
     * 从库数据源
     */
    @Bean(name = DataSourceConst.test_01_SLAVE)
    @ConfigurationProperties("spring.datasource.test01-slave")
    public DataSource test01Slave() {
        return DruidDataSourceBuilder.create().build();
    }

    /**
     * 数据源02
     */
    @Bean(name = DataSourceConst.test_02_SLAVE)
    @ConfigurationProperties("spring.datasource.test02-slave")
    public DataSource test02Slave() {
        return DruidDataSourceBuilder.create().build();
    }


    @Bean(name = "dynamicDataSource")
    @Primary
    public DynamicDataSource dynamicDataSource(@Qualifier("test01") DataSource test01, @Qualifier("test02") DataSource test02,
                                               @Qualifier("test01-slave") DataSource test01Slave, @Qualifier("test02-slave") DataSource test02Slave) {
        //构建数据源集合
        Map<Object, Object> dataSourceMap = new HashMap<>(5);
        dataSourceMap.put(DataSourceConst.test_01, test01);
        dataSourceMap.put(DataSourceConst.test_02, test02);
        dataSourceMap.put(DataSourceConst.test_01_SLAVE, test01Slave);
        dataSourceMap.put(DataSourceConst.test_02_SLAVE, test02Slave);
        return new DynamicDataSource(test01, dataSourceMap);
    }


    @Bean(name = "tidbJdbcTemplate")
    public JdbcTemplate tidbJdbcTemplate(@Qualifier("dynamicDataSource") DataSource dataSource) {
        return new JdbcTemplate(dataSource);
    }


}

 3.在公共模块配置所需配置Bean

public class DataSourceConst {

    public static final String test_01 = "test01";

    public static final String test_02 = "test02";

    public static final String test_01_SLAVE = "test01-slave";

    public static final String test_02_SLAVE = "test02-slave";


    /获取仓库编码字段//
    public static final String WH_CODE = "whCode";


    ///获取动态数据源redisKey///

    public static final String DATA_SOURCE_REDIS_KEY = "dynamic:data:source:";

    public static final String DATA_SOURCE_PROJECT_REDIS_KEY = "dynamic:project:data:source:";
	
}	

4.创建自定义异常类及枚举值

/**
 * 异常错误code
 * 重复操作
 */
@AllArgsConstructor
@Getter
public enum ErrorCodeEnum {

    VALID_ERROR_MESSAGE("10001", "参数校验异常"),
    ERROR_PARAMS("10002", "参数异常");

    private String code;
    private String message;

}
@Setter
@Getter
public class CustomException extends RuntimeException{

    private String code;
    private String message;

    public CustomException(String message) {
        this.message = message;
    }

    public CustomException(ErrorCodeEnum errorCodeEnum) {

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

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

相关文章

佳明运动相机SD存储卡被格式化?教你有效恢复数据的方法

在日常使用佳明运动相机的过程中&#xff0c;‌我们可能会不小心将SD存储卡格式化&#xff0c;‌导致珍贵的照片和视频数据丢失。‌面对这种情况&#xff0c;‌很多用户都感到十分焦虑和无助。‌但幸运的是&#xff0c;‌通过一些有效的方法&#xff0c;‌我们仍然有可能恢复这…

如何在Centos7构建调试“Jmeter-InfluxDB-Grafana“?

一、数据源配置 1、在"Grafana"首页&#xff0c;添加数据源 2、点击添加 3、选择"InfluxDB" 4、填写主机 5、填写"Database&#xff1a;jmeter"和"HTTP Method&#xff1a;GET" 6、点击"Save & test" 7、查看 二、配置…

串口与Labview通讯的调试

在学习Labview和串口的通讯和调试的时候。首先必须先了解一些Labview的基础知识&#xff0c;然后就是了解串口&#xff0c;在调试的过程中&#xff0c;我们需要下位机来辅助我们的程序编写与调试&#xff0c;也就是我们平时使用的单片机&#xff0c;如果没有单片机也不要紧&…

不会抖音剪辑怎么办?这4款拿走不谢

不少人想做自媒体&#xff0c;但是就光视频剪辑这一点难住了不少人&#xff0c;其实视频剪辑并没有大家想的那么复杂&#xff0c;直接用一些简单的剪辑视频工具也可以处理。作为一个短视频剪辑新手&#xff0c;我最近尝试了几款流行的视频编辑软件&#xff0c;今天就来和大家分…

Docker(完整实验版)

目录 一 Docker 1.1 Docker简介 1.1.1 什么是docker&#xff1f; 1.1.2 docker在企业中的应用场景 1.1.3 docker与虚拟化的对比 1.1.4 docker的优势 1.2 部署docker 1.2.1 配置软件仓库 二 Docker的基本操作 2.1 Docker镜像管理 2.1.1 搜索镜像 2.1.2 拉取镜像 2…

【串的相关概念】

1.前情回顾&#xff1a; 2.串的定义 注意这里的字符是任意字符&#xff1a;包括特殊字符和空格 2.1串的相关术语 2.2分析如下&#xff1a; 子串与主串 可以类比 子集与集合的关系 且空串也是子串的一种 注意空格串与空串的区别 位置是从1开始设定的&#xff08;第一个位置开始…

【java入门】关键字、标识符与变量初识

&#x1f680; 个人简介&#xff1a;某大型国企资深软件开发工程师&#xff0c;信息系统项目管理师、CSDN优质创作者、阿里云专家博主&#xff0c;华为云云享专家&#xff0c;分享前端后端相关技术与工作常见问题~ &#x1f49f; 作 者&#xff1a;码喽的自我修养&#x1f9…

Java 入门指南:Java 并发编程 —— 并发容器 PriorityBlockingQueue

BlockingQueue BlockingQueue 是Java并发包&#xff08;java.util.concurrent&#xff09;中提供的一个阻塞队列接口&#xff0c;它继承自 Queue 接口。 BlockingQueue 中的元素采用 FIFO 的原则&#xff0c;支持多线程环境并发访问&#xff0c;提供了阻塞读取和写入的操作&a…

「C++」类和对象(2)

欢迎大家来到小鸥的类和对象第二篇博客~ 目录 类的默认成员函数 构造函数 构造函数的特点&#xff1a; 析构函数 析构函数的特点&#xff1a; 拷贝构造函数 拷贝构造的特点&#xff1a; 结语&#xff1a; 本篇会着重讲解类和对象中的难点&#xff1a;类的默认成员函数 …

Ubuntu环境的MySql下载安装

下载压缩包 此文章下载的mysql版本位5.7.29 sudo wget https://downloads.mysql.com/archives/get/p/23/file/mysql-server_5.7.29-1ubuntu18.04_amd64.deb-bundle.tar解压缩 sudo tar -xvf mysql-server_5.7.29-1ubuntu18.04_amd64.deb-bundle.tar命令解释 -x&#xff1a;…

鸿蒙Next-拉起支付宝的三种方式——教程

鸿蒙Next-拉起支付宝的三种方式——教程 鸿蒙Next系统即将上线&#xff0c;应用市场逐渐丰富、很多APP都准备接入支付宝做支付功能&#xff0c;目前来说有三种方式拉起支付宝&#xff1a;通过支付宝SDK拉起、使用OpenLink拉起、传入支付宝包名使用startAbility拉起。以上的三种…

走心机做不锈钢哪个牌子好

不锈钢是现代生活中不可或缺的材料&#xff0c;它广泛应用于厨房用具、家具、建筑等领域。在市场上&#xff0c;有许多不锈钢需要加工零件供消费者选择&#xff0c;那么在选择不锈钢加工零件时制品时&#xff0c;应该如何选择数控走心机&#xff0c;找到最好的品牌呢&#xff1…

CodeSys中动态切换3D模型

文章目录 需求研究结果 需求 在前面的【CodeSys开发3d机械臂显示控件】中&#xff0c;我们已经实现了一个可以显示3d模型的控件。但是这个控件是和使用的3d模型绑定死的&#xff0c;在安装这个控件时就已经将模型文件于控件一起安装到codesys中。 假如我想在不同的工程中&…

Numpy中type()、ndim、shape、size、dtype、astype的用法

目录 numpy基础介绍示例分析及总结&#xff1a;itemsize、nbytes函数 numpy基础介绍 Numpy 补充了Python语言所欠缺的数值计算能力,是其它数据分析及机器学习库的底层库。因其完全标准C语言实现&#xff0c;运行效率充分优化。最重要一点是开源免费。numpy的核心是矩阵&#x…

思维导图怎么画好看又简单?5个软件帮助你快速进行思维导图绘制

思维导图怎么画好看又简单&#xff1f;5个软件帮助你快速进行思维导图绘制 思维导图是一种有效的思维整理和展示工具&#xff0c;可以帮助你将复杂的想法进行可视化&#xff0c;提升工作和学习效率。为了让思维导图既好看又简单&#xff0c;选择合适的软件能够大大提高绘制效率…

UE中Camera Clip截面修改

UE中Camera无法修改远截面&#xff08;FarClipingPlane)&#xff0c;只可修改近截面&#xff08;NearClipingPlane&#xff09;&#xff1a; 至于为什么无法修改远截面&#xff0c;看下代码&#xff0c;尝试继承UE的CameraComponent打印出相机投影矩阵&#xff1a; #include …

python编程知识(实现数据加密和解密)

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;开发者-曼亿点 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 曼亿点 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a…

在模板中使用 Django 会话

在 Django 中使用会话&#xff08;session&#xff09;可以让你在用户访问网站的过程中存储和访问临时数据。我们可以利用会话在速度计算器的例子中存储和显示上次计算的结果。 1、问题背景 在 Django 中&#xff0c;可以使用会话来存储用户数据。在某些情况下&#xff0c;我们…

双绞线如何抑制传导干扰

一&#xff0e;案例简介 产品去做CE认证时&#xff0c;被告知传导抗扰未通过&#xff0c;网络会断连。 剖开网线外皮&#xff0c;发现内部是散装的&#xff0c;非双绞线。因此换成双绞线网线&#xff0c;复测&#xff0c;传导抗扰通过了。 图1 非双绞线和双绞线示意图 为什么…