当前位置: 首页 > news >正文

SpringBoot多数据源架构实现

文章目录

    • 1. 环境准备
    • 2. 创建Spring Boot项目
    • 3. 添加依赖
    • 4. 配置多数据源
    • 5. 配置MyBatis-Plus
    • 6. 使用多数据源
    • 7. 创建Mapper接口
    • 8. 实体类定义
    • 9. 测试多数据源
    • 10. 注意事项
      • 10.1 事务导致多数据源失效问题
        • 解决方案:
      • 10.2 ClickHouse的事务支持
      • 10.3 数据源切换的性能开销
      • 10.4 数据源配置的优先级
    • 11. 总结

使用Spring Boot 3.x + MyBatis-Plus + MySQL 8.0 + ClickHouse 24 实现多数据源配置

在现代的应用程序开发中,使用多个数据源已经成为一种常见的需求。例如,我们可能需要在同一个应用中使用MySQL作为主数据库,同时使用ClickHouse来处理大量的分析数据。本文将介绍如何使用Spring Boot 3.x、MyBatis-Plus、MySQL 8.0和ClickHouse 24,结合dynamic-datasource-spring-boot-starter实现多数据源配置。

1. 环境准备

在开始之前,确保你已经准备好以下环境:

  • JDK 17 或更高版本
  • Spring Boot 3.x
  • MySQL 8.0
  • ClickHouse 24
  • Maven 或 Gradle

2. 创建Spring Boot项目

首先,创建一个新的Spring Boot项目。你可以使用Spring Initializr来生成项目骨架,选择以下依赖:

  • Spring Web
  • MyBatis Framework
  • MySQL Driver
  • ClickHouse Driver

3. 添加依赖

pom.xml中添加以下依赖:

<dependencies><!-- Spring Boot Starter --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><version>3.0.0</springBoot></dependency><!-- MyBatis-Plus --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.3.1</version></dependency><!-- MySQL Driver --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.33</version></dependency><!-- ClickHouse JDBC driver --><dependency><groupId>ru.yandex.clickhouse</groupId><artifactId>clickhouse-jdbc</artifactId><version>0.3.2</version></dependency><!-- Dynamic Datasource --><dependency><groupId>com.baomidou</groupId><artifactId>dynamic-datasource-spring-boot-starter</artifactId><version>3.6.1</version></dependency>
</dependencies>

4. 配置多数据源

application.yml中配置MySQL和ClickHouse的数据源:

spring:datasource:dynamic:primary: master # 设置默认的数据源strict: false # 是否严格匹配数据源,不严格匹配时,找不到对应数据源会使用默认数据源datasource:master:url: jdbc:mysql://localhost:3306/mydb?useUnicode=true&connectTimeout=30000&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true&allowPublicKeyRetrieval=trueusername: rootpassword: rootdriver-class-name: com.mysql.cj.jdbc.Driverdw:url: jdbc:clickhouse://localhost:8123/mzdb?timezone=Asia/Shanghai&socket_timeout=600000&connect_timeout=60000username: defaultpassword: driver-class-name: com.clickhouse.jdbc.ClickHouseDriver

5. 配置MyBatis-Plus

在Spring Boot中配置MyBatis-Plus,确保它能够支持多数据源。

@Configuration
@MapperScan("com.example.mapper")
public class MybatisPlusConfig {@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));return interceptor;}
}

6. 使用多数据源

在代码中使用@DS注解来指定使用哪个数据源。@DS注解可以放在类或方法上。

@DS注解可以使用在mapper接口上,也可以使用在方法上,也可以使用在Service类上,取决于业务中需要实现的作用域

@Service
public class UserService {@Autowiredprivate UserMapper userMapper;public List<User> getUsers() {return userMapper.selectList(null);}@DS("clickhouse") // 切换为clickhouse数据源public List<DwOperationRecordMapper> getAnalyticsData() {return analyticsMapper.selectList(null);}
}

7. 创建Mapper接口

创建对应的Mapper接口,并使用@Mapper注解标记。

/**
* 主数据源
*/
@Mapper
public interface SysUserMapper extends BaseMapper<SysUser> {
}
/**
* 副数据源
*/
@Mapper
@DS("dw") //切换为clickhouse数据源
public interface DwOperationRecordMapper extends BaseMapper<DwOperationRecord> {
}

8. 实体类定义

定义对应的实体类,并使用@TableName注解指定表名。

/**
* 主数据源
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@TableName(value = "sys_user")
public class SysUser {//账号状态_启用public final static Integer FORBIDDEN = 0;@TableId(type = IdType.AUTO)private Long id;@Schema(description = "姓名")private String name;@Schema(description = "密码")private String password;@Schema(description = "账号名")private String userName;@Schema(description = "手机号")private String phone;
}/**
* 副数据源
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@TableName("DWS_OPERATION_RECORD")
public class DwOperationRecord implements Serializable {/*** 手术记录id*/@TableField(value = "surgical_id",exist = false)@Schema(description = "手术记录id")private String surgicalId;/*** 病案号*/@Schema(description ="病案号")private String patientid;/*** 姓名*/@Schema(description ="姓名")private String name;/*** 性别*/@Schema(description ="性别")private String sex;
}

9. 测试多数据源

编写测试类,验证多数据源是否正常工作。

@SpringBootTest
public class MultiDataSourceTest {@Autowiredprivate UserService userService;@Testpublic void testMySQLDataSource() {List<SysUser> users = userService.getUsers();Assert.notEmpty(users, "MySQL数据源查询失败");}@Testpublic void testClickHouseDataSource() {List<DwOperationRecord> list = userService.list();Assert.notEmpty(list, "ClickHouse数据源查询失败");}
}

10. 注意事项

10.1 事务导致多数据源失效问题

在使用多数据源时,如果开启了事务(@Transactional),可能会导致数据源切换失效。这是因为Spring的事务管理机制默认会绑定一个数据源,事务开启后不会动态切换数据源。

解决方案:
  1. 禁用事务
    如果业务场景允许,可以在切换数据源的方法上禁用事务:

    @DS("dw")
    @Transactional(rollbackFor = SQLException.class, propagation = Propagation.NOT_SUPPORTED) // 禁用事务
    public List<DwOperationRecord> getDwOperationRecord() {return dwOperationRecordMapper.selectList(null);
    }
    
  2. 使用@DSTransactional注解
    dynamic-datasource-spring-boot-starter提供了@DSTransactional注解,支持多数据源事务管理。需要在主数据源上开启事务,其他数据源不支持事务。

    @Transactional(rollbackFor = SQLException.class) // 主数据源事务
    public void updateUserAndLog(SysUser user) {userMapper.updateById(user);logToClickhouse(user); // 切换到ClickHouse
    }@DS("clickhouse")
    public void logToClickhouse(SysUser user) {dwOperationRecordMapper.insert(new DwOperationRecord(user.getId(), "UPDATE", LocalDateTime.now()));
    }
    
  3. 手动控制事务
    如果必须使用事务,可以手动控制事务的提交和回滚:

    @Autowired
    private DataSourceTransactionManager transactionManager;// 默认使用主数据源
    public void updateUserAndLog(SysUser user) {DefaultTransactionDefinition definition = new DefaultTransactionDefinition();TransactionStatus status = transactionManager.getTransaction(definition);try {userMapper.updateById(user);logToClickhouse(user); // 切换到ClickHousetransactionManager.commit(status);} catch (Exception e) {transactionManager.rollback(status);throw e;}
    }
    

10.2 ClickHouse的事务支持

ClickHouse本身不支持事务(ACID),因此在使用ClickHouse时,无法使用事务管理。如果需要保证数据一致性,可以通过业务逻辑或补偿机制来实现。


10.3 数据源切换的性能开销

频繁切换数据源可能会带来一定的性能开销,尤其是在高并发场景下。建议尽量减少数据源切换的次数,或者通过缓存机制优化数据访问。


10.4 数据源配置的优先级

如果同时配置了spring.datasource.urldynamic-datasourcedynamic-datasource会覆盖默认的spring.datasource配置。确保只使用一种配置方式,避免冲突。

11. 总结

通过以上步骤,我们成功地在Spring Boot 3.x项目中配置了MySQL和ClickHouse的多数据源,并使用MyBatis-Plus进行数据操作。dynamic-datasource-spring-boot-starter使得多数据源的切换变得非常简单,只需通过@DS注解即可轻松切换数据源。

在实际项目中,多数据源的配置可能会更加复杂,例如涉及到事务管理、读写分离等。但通过本文的介绍,你已经掌握了基本的配置方法,可以根据实际需求进行扩展和优化。

注意事项

  • 事务管理在多数据源场景下需要特别处理,避免数据源切换失效。
  • ClickHouse不支持事务,需通过业务逻辑保证数据一致性。
  • 尽量减少数据源切换的频率,优化性能。

希望本文对你有所帮助,祝你在使用Spring Boot开发多数据源应用时顺利!

相关文章:

SpringBoot多数据源架构实现

文章目录 1. 环境准备2. 创建Spring Boot项目3. 添加依赖4. 配置多数据源5. 配置MyBatis-Plus6. 使用多数据源7. 创建Mapper接口8. 实体类定义9. 测试多数据源10. 注意事项10.1 事务导致多数据源失效问题解决方案&#xff1a; 10.2 ClickHouse的事务支持10.3 数据源切换的性能开…...

HarmonyOS开发:传参方式

一、父子组件传参 1、父传子&#xff08;Prop方式&#xff09; 父组件代码 Entry Component struct ParentComponent {State parentMessage: string Hello from Parent;build() {Column() {ChildComponent({ message: this.parentMessage });}} } 子组件代码 Component s…...

OpenCV计算机视觉 07 图像的模块匹配

在做目标检测、图像识别时&#xff0c;我们经常用到模板匹配&#xff0c;以确定模板在输入图像中的可能位置 API函数 cv2.matchTemplate(image, templ, method, resultNone, maskNone) 参数含义&#xff1a; image&#xff1a;待搜索图像 templ&#xff1a;模板图像 method&…...

国产游戏崛起,燕云十六移动端1.9上线,ToDesk云电脑先开玩

游戏爱好者的利好消息出新了&#xff01;网易大型武侠仙游《燕云十六声》正式官宣&#xff0c;移动端要在1月9日正式上线了&#xff01;你期待手游版的燕云吗&#xff1f;不妨评论区留言说说你的看法。小编分别花了几个小时在台式机电脑和手机上都试了下&#xff0c;欣赏画面还…...

企业级PHP异步RabbitMQ协程版客户端 2.0 正式发布

概述 workerman/rabbitmq 是一个异步RabbitMQ客户端&#xff0c;使用AMQP协议。 RabbitMQ是一个基于AMQP&#xff08;高级消息队列协议&#xff09;实现的开源消息组件&#xff0c;它主要用于在分布式系统中存储和转发消息。RabbitMQ由高性能、高可用以及高扩展性出名的Erlan…...

[OPEN SQL] 限定选择行数

本次操作使用的数据库表为SCUSTOM&#xff0c;其字段内容如下所示 航班用户(SCUSTOM) 该数据库表中的部分值如下所示 指定查询多少行数据&#xff0c;我们可以使用语法UP TO n ROWS来实现对数据前n项的查询 语法格式 SELECT * FROM <dbtab> UP TO n ROWS 参数说明 db…...

Vite源码学习分享(一)

!](https://i-blog.csdnimg.cn/direct/971c35b61c57402b95be91d2b4965d85.png) 同一个项目 vite VS webpack启动速度对比...

定位,用最通俗易懂的方法2:TDOA与对应的CRLB

二郎就不设置什么VIP可见啥的了&#xff0c;这样大家都能看到。 如果觉得受益&#xff0c;可以给予一些打赏&#xff0c;也算对原创的一些鼓励&#xff0c;谢谢。 钱的用途&#xff1a;1&#xff09;布施给他人&#xff1b;2&#xff09;二郎会有更多空闲时间写教程 起因&…...

Linux第一课:c语言 学习记录day06

四、数组 冒泡排序 两两比较&#xff0c;第 j 个和 j1 个比较 int a[5] {5, 4, 3, 2, 1}; 第一轮&#xff1a;i 0 n&#xff1a;n个数&#xff0c;比较 n-1-i 次 4 5 3 2 1 // 第一次比较 j 0 4 3 5 2 1 // 第二次比较 j 1 4 3 2 5 1 // 第三次比较 j 2 4 3 2 1 5 // …...

ExplaineR:集成K-means聚类算法的SHAP可解释性分析 | 可视化混淆矩阵、决策曲线、模型评估与各类SHAP图

集成K-means聚类算法的SHAP可解释性分析 加载数据集并训练机器学习模型 SHAP 分析以提取特征对预测的影响 通过混淆矩阵可视化模型性能 决策曲线分析 模型评估&#xff08;多指标和ROC曲线的目视检查&#xff09; 带注释阈值的 ROC 曲线 加载 SHAP 结果以进行下游分析 与…...

2025年第三届“华数杯”国际大学生数学建模竞赛A题题目

问题A&#xff1a;他能游得更快吗&#xff1f; 背景介绍 在2024年巴黎奥运会上&#xff0c;中国游泳运动员潘展乐凭借出色的表现成为全球瞩目的焦点。年仅19岁的他在男子100米自由泳比赛中以46秒40 的成绩夺冠&#xff0c;并创造了自己保持的世界纪录。在男子4100米混合泳接力…...

用c实现C++类(八股)

在 C 语言中&#xff0c;虽然没有内建的面向对象编程&#xff08;OOP&#xff09;特性&#xff08;如封装、继承、多态&#xff09;&#xff0c;但通过一些编程技巧&#xff0c;我们仍然可以模拟实现这些概念。下面将用通俗易懂的方式&#xff0c;逐步介绍如何在 C 中实现封装、…...

【C++多线程编程:六种锁】

目录 普通互斥锁&#xff1a; 轻量级锁 独占锁&#xff1a; std::lock_guard&#xff1a; std::unique_lock: 共享锁&#xff1a; 超时的互斥锁 递归锁 普通互斥锁&#xff1a; std::mutex确保任意时刻只有一个线程可以访问共享资源&#xff0c;在多线程中常用于保…...

【Javascript Day5】for循环及典型案例

for 循环 // 语法&#xff1a; for( 开始 ; 结束 ; 步长 ){ 循环体 } // for( var i 循环初始值 ; i的循环范围 ; i的增加或减少规则 ){ 循环体 } // 死循环 // for(;;){ // console.log("for循环"); // } // 循环打…...

#渗透测试#网络安全#一文了解什么是shell反弹!!!

免责声明 本教程仅为合法的教学目的而准备&#xff0c;严禁用于任何形式的违法犯罪活动及其他商业行为&#xff0c;在使用本教程前&#xff0c;您应确保该行为符合当地的法律法规&#xff0c;继续阅读即表示您需自行承担所有操作的后果&#xff0c;如有异议&#xff0c;请立即停…...

《解锁图像的语言密码:Image Caption 开源神经网络项目全解析》

《解锁图像的语言密码&#xff1a;Image Caption 开源项目全解析》 一、开篇&#xff1a;AI 看图说话时代来临二、走进 Image Caption 开源世界三、核心技术拆解&#xff1a;AI 如何学会看图说话&#xff08;一&#xff09;深度学习双雄&#xff1a;CNN 与 RNN&#xff08;二&a…...

抢占欧洲电商高地,TikTok 运营专线成 “秘密武器”

在当今数字化浪潮席卷全球的时代&#xff0c;社交媒体平台已成为商业拓展的关键阵地&#xff0c;TikTok 更是其中的闪耀新星。近日&#xff0c;一则重磅消息引发行业关注&#xff1a;TikTok 正计划于 2025 年初进军荷兰电商市场。这一战略布局&#xff0c;不仅彰显了 TikTok 对…...

人工智能-数据分析及特征提取思路

1、概况 基于学生行为数据预测是否涉黄、涉黑等。 2.数据分析 数据分析的意义包括得到数据得直觉、发掘潜在的结构、提取重要的变量、删除异常值、检验潜在的假设和建立初步的模型。 2.1数据质量分析 2.1.1数据值分析 查看数据类型&#xff1a; 首先明确各字段的数据类型…...

2024 China Collegiate Programming Contest (CCPC) Zhengzhou Onsite 基础题题解

今天先发布基础题的题解&#xff0c;明天再发布铜牌题和银牌题的题解 L. Z-order Curve 思路&#xff1a;这题目说了&#xff0c;上面那一行&#xff0c;只有在偶数位才有可能存在1&#xff0c;那么一定存在这样的数&#xff0c;0 ,1,100, 10000,那么反之&#xff0c;我们的数…...

halcon3d 如何计算平面法向量!确实很简单

这个问题其实一直困扰了我很长时间,之前是怎么算的呢 对于一个平面,我会先求它的fit_primitives_object_model_3d去将它拟合,接下来用surface_normals_object_model_3d 算子生成它的法线,后用get_object_model_3d_params (ObjectModel3DNormals, ‘point_normal_x’, GenP…...

K8S认证|CKS题库+答案| 11. AppArmor

目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作&#xff1a; 1&#xff09;、切换集群 2&#xff09;、切换节点 3&#xff09;、切换到 apparmor 的目录 4&#xff09;、执行 apparmor 策略模块 5&#xff09;、修改 pod 文件 6&#xff09;、…...

基于Uniapp开发HarmonyOS 5.0旅游应用技术实践

一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架&#xff0c;支持"一次开发&#xff0c;多端部署"&#xff0c;可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务&#xff0c;为旅游应用带来&#xf…...

Psychopy音频的使用

Psychopy音频的使用 本文主要解决以下问题&#xff1a; 指定音频引擎与设备&#xff1b;播放音频文件 本文所使用的环境&#xff1a; Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...

VTK如何让部分单位不可见

最近遇到一个需求&#xff0c;需要让一个vtkDataSet中的部分单元不可见&#xff0c;查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行&#xff0c;是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示&#xff0c;主要是最后一个参数&#xff0c;透明度…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)

宇树机器人多姿态起立控制强化学习框架论文解析 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架&#xff08;一&#xff09; 论文解读&#xff1a;交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...

【配置 YOLOX 用于按目录分类的图片数据集】

现在的图标点选越来越多&#xff0c;如何一步解决&#xff0c;采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集&#xff08;每个目录代表一个类别&#xff0c;目录下是该类别的所有图片&#xff09;&#xff0c;你需要进行以下配置步骤&#x…...

ElasticSearch搜索引擎之倒排索引及其底层算法

文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...

GitHub 趋势日报 (2025年06月08日)

&#x1f4ca; 由 TrendForge 系统生成 | &#x1f310; https://trendforge.devlive.org/ &#x1f310; 本日报中的项目描述已自动翻译为中文 &#x1f4c8; 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...

Java入门学习详细版(一)

大家好&#xff0c;Java 学习是一个系统学习的过程&#xff0c;核心原则就是“理论 实践 坚持”&#xff0c;并且需循序渐进&#xff0c;不可过于着急&#xff0c;本篇文章推出的这份详细入门学习资料将带大家从零基础开始&#xff0c;逐步掌握 Java 的核心概念和编程技能。 …...

ABAP设计模式之---“简单设计原则(Simple Design)”

“Simple Design”&#xff08;简单设计&#xff09;是软件开发中的一个重要理念&#xff0c;倡导以最简单的方式实现软件功能&#xff0c;以确保代码清晰易懂、易维护&#xff0c;并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计&#xff0c;遵循“让事情保…...