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的事务管理机制默认会绑定一个数据源,事务开启后不会动态切换数据源。
解决方案:
-
禁用事务
如果业务场景允许,可以在切换数据源的方法上禁用事务:@DS("dw") @Transactional(rollbackFor = SQLException.class, propagation = Propagation.NOT_SUPPORTED) // 禁用事务 public List<DwOperationRecord> getDwOperationRecord() {return dwOperationRecordMapper.selectList(null); } -
使用
@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())); } -
手动控制事务
如果必须使用事务,可以手动控制事务的提交和回滚:@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.url和dynamic-datasource,dynamic-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 事务导致多数据源失效问题解决方案: 10.2 ClickHouse的事务支持10.3 数据源切换的性能开…...
HarmonyOS开发:传参方式
一、父子组件传参 1、父传子(Prop方式) 父组件代码 Entry Component struct ParentComponent {State parentMessage: string Hello from Parent;build() {Column() {ChildComponent({ message: this.parentMessage });}} } 子组件代码 Component s…...
OpenCV计算机视觉 07 图像的模块匹配
在做目标检测、图像识别时,我们经常用到模板匹配,以确定模板在输入图像中的可能位置 API函数 cv2.matchTemplate(image, templ, method, resultNone, maskNone) 参数含义: image:待搜索图像 templ:模板图像 method&…...
国产游戏崛起,燕云十六移动端1.9上线,ToDesk云电脑先开玩
游戏爱好者的利好消息出新了!网易大型武侠仙游《燕云十六声》正式官宣,移动端要在1月9日正式上线了!你期待手游版的燕云吗?不妨评论区留言说说你的看法。小编分别花了几个小时在台式机电脑和手机上都试了下,欣赏画面还…...
企业级PHP异步RabbitMQ协程版客户端 2.0 正式发布
概述 workerman/rabbitmq 是一个异步RabbitMQ客户端,使用AMQP协议。 RabbitMQ是一个基于AMQP(高级消息队列协议)实现的开源消息组件,它主要用于在分布式系统中存储和转发消息。RabbitMQ由高性能、高可用以及高扩展性出名的Erlan…...
[OPEN SQL] 限定选择行数
本次操作使用的数据库表为SCUSTOM,其字段内容如下所示 航班用户(SCUSTOM) 该数据库表中的部分值如下所示 指定查询多少行数据,我们可以使用语法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可见啥的了,这样大家都能看到。 如果觉得受益,可以给予一些打赏,也算对原创的一些鼓励,谢谢。 钱的用途:1)布施给他人;2)二郎会有更多空闲时间写教程 起因&…...
Linux第一课:c语言 学习记录day06
四、数组 冒泡排序 两两比较,第 j 个和 j1 个比较 int a[5] {5, 4, 3, 2, 1}; 第一轮:i 0 n:n个数,比较 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 分析以提取特征对预测的影响 通过混淆矩阵可视化模型性能 决策曲线分析 模型评估(多指标和ROC曲线的目视检查) 带注释阈值的 ROC 曲线 加载 SHAP 结果以进行下游分析 与…...
2025年第三届“华数杯”国际大学生数学建模竞赛A题题目
问题A:他能游得更快吗? 背景介绍 在2024年巴黎奥运会上,中国游泳运动员潘展乐凭借出色的表现成为全球瞩目的焦点。年仅19岁的他在男子100米自由泳比赛中以46秒40 的成绩夺冠,并创造了自己保持的世界纪录。在男子4100米混合泳接力…...
用c实现C++类(八股)
在 C 语言中,虽然没有内建的面向对象编程(OOP)特性(如封装、继承、多态),但通过一些编程技巧,我们仍然可以模拟实现这些概念。下面将用通俗易懂的方式,逐步介绍如何在 C 中实现封装、…...
【C++多线程编程:六种锁】
目录 普通互斥锁: 轻量级锁 独占锁: std::lock_guard: std::unique_lock: 共享锁: 超时的互斥锁 递归锁 普通互斥锁: std::mutex确保任意时刻只有一个线程可以访问共享资源,在多线程中常用于保…...
【Javascript Day5】for循环及典型案例
for 循环 // 语法: for( 开始 ; 结束 ; 步长 ){ 循环体 } // for( var i 循环初始值 ; i的循环范围 ; i的增加或减少规则 ){ 循环体 } // 死循环 // for(;;){ // console.log("for循环"); // } // 循环打…...
#渗透测试#网络安全#一文了解什么是shell反弹!!!
免责声明 本教程仅为合法的教学目的而准备,严禁用于任何形式的违法犯罪活动及其他商业行为,在使用本教程前,您应确保该行为符合当地的法律法规,继续阅读即表示您需自行承担所有操作的后果,如有异议,请立即停…...
《解锁图像的语言密码:Image Caption 开源神经网络项目全解析》
《解锁图像的语言密码:Image Caption 开源项目全解析》 一、开篇:AI 看图说话时代来临二、走进 Image Caption 开源世界三、核心技术拆解:AI 如何学会看图说话(一)深度学习双雄:CNN 与 RNN(二&a…...
抢占欧洲电商高地,TikTok 运营专线成 “秘密武器”
在当今数字化浪潮席卷全球的时代,社交媒体平台已成为商业拓展的关键阵地,TikTok 更是其中的闪耀新星。近日,一则重磅消息引发行业关注:TikTok 正计划于 2025 年初进军荷兰电商市场。这一战略布局,不仅彰显了 TikTok 对…...
人工智能-数据分析及特征提取思路
1、概况 基于学生行为数据预测是否涉黄、涉黑等。 2.数据分析 数据分析的意义包括得到数据得直觉、发掘潜在的结构、提取重要的变量、删除异常值、检验潜在的假设和建立初步的模型。 2.1数据质量分析 2.1.1数据值分析 查看数据类型: 首先明确各字段的数据类型…...
2024 China Collegiate Programming Contest (CCPC) Zhengzhou Onsite 基础题题解
今天先发布基础题的题解,明天再发布铜牌题和银牌题的题解 L. Z-order Curve 思路:这题目说了,上面那一行,只有在偶数位才有可能存在1,那么一定存在这样的数,0 ,1,100, 10000,那么反之,我们的数…...
halcon3d 如何计算平面法向量!确实很简单
这个问题其实一直困扰了我很长时间,之前是怎么算的呢 对于一个平面,我会先求它的fit_primitives_object_model_3d去将它拟合,接下来用surface_normals_object_model_3d 算子生成它的法线,后用get_object_model_3d_params (ObjectModel3DNormals, ‘point_normal_x’, GenP…...
Debian系统简介
目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版ÿ…...
定时器任务——若依源码分析
分析util包下面的工具类schedule utils: ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类,封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz,先构建任务的 JobD…...
剑指offer20_链表中环的入口节点
链表中环的入口节点 给定一个链表,若其中包含环,则输出环的入口节点。 若其中不包含环,则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...
Nginx server_name 配置说明
Nginx 是一个高性能的反向代理和负载均衡服务器,其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机(Virtual Host)。 1. 简介 Nginx 使用 server_name 指令来确定…...
相机从app启动流程
一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...
EtherNet/IP转DeviceNet协议网关详解
一,设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络,本网关连接到EtherNet/IP总线中做为从站使用,连接到DeviceNet总线中做为从站使用。 在自动…...
Redis的发布订阅模式与专业的 MQ(如 Kafka, RabbitMQ)相比,优缺点是什么?适用于哪些场景?
Redis 的发布订阅(Pub/Sub)模式与专业的 MQ(Message Queue)如 Kafka、RabbitMQ 进行比较,核心的权衡点在于:简单与速度 vs. 可靠与功能。 下面我们详细展开对比。 Redis Pub/Sub 的核心特点 它是一个发后…...
springboot整合VUE之在线教育管理系统简介
可以学习到的技能 学会常用技术栈的使用 独立开发项目 学会前端的开发流程 学会后端的开发流程 学会数据库的设计 学会前后端接口调用方式 学会多模块之间的关联 学会数据的处理 适用人群 在校学生,小白用户,想学习知识的 有点基础,想要通过项…...
JavaScript基础-API 和 Web API
在学习JavaScript的过程中,理解API(应用程序接口)和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能,使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...
Visual Studio Code 扩展
Visual Studio Code 扩展 change-case 大小写转换EmmyLua for VSCode 调试插件Bookmarks 书签 change-case 大小写转换 https://marketplace.visualstudio.com/items?itemNamewmaurer.change-case 选中单词后,命令 changeCase.commands 可预览转换效果 EmmyLua…...
