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…...
<6>-MySQL表的增删查改
目录 一,create(创建表) 二,retrieve(查询表) 1,select列 2,where条件 三,update(更新表) 四,delete(删除表…...
微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】
微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来,Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...
2.Vue编写一个app
1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...
【CSS position 属性】static、relative、fixed、absolute 、sticky详细介绍,多层嵌套定位示例
文章目录 ★ position 的五种类型及基本用法 ★ 一、position 属性概述 二、position 的五种类型详解(初学者版) 1. static(默认值) 2. relative(相对定位) 3. absolute(绝对定位) 4. fixed(固定定位) 5. sticky(粘性定位) 三、定位元素的层级关系(z-i…...
k8s业务程序联调工具-KtConnect
概述 原理 工具作用是建立了一个从本地到集群的单向VPN,根据VPN原理,打通两个内网必然需要借助一个公共中继节点,ktconnect工具巧妙的利用k8s原生的portforward能力,简化了建立连接的过程,apiserver间接起到了中继节…...
【JavaSE】绘图与事件入门学习笔记
-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角,以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向,距离坐标原点x个像素;第二个是y坐标,表示当前位置为垂直方向,距离坐标原点y个像素。 坐标体系-像素 …...
Redis数据倾斜问题解决
Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中,部分节点存储的数据量或访问量远高于其他节点,导致这些节点负载过高,影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...
让回归模型不再被异常值“带跑偏“,MSE和Cauchy损失函数在噪声数据环境下的实战对比
在机器学习的回归分析中,损失函数的选择对模型性能具有决定性影响。均方误差(MSE)作为经典的损失函数,在处理干净数据时表现优异,但在面对包含异常值的噪声数据时,其对大误差的二次惩罚机制往往导致模型参数…...
【C++进阶篇】智能指针
C内存管理终极指南:智能指针从入门到源码剖析 一. 智能指针1.1 auto_ptr1.2 unique_ptr1.3 shared_ptr1.4 make_shared 二. 原理三. shared_ptr循环引用问题三. 线程安全问题四. 内存泄漏4.1 什么是内存泄漏4.2 危害4.3 避免内存泄漏 五. 最后 一. 智能指针 智能指…...
适应性Java用于现代 API:REST、GraphQL 和事件驱动
在快速发展的软件开发领域,REST、GraphQL 和事件驱动架构等新的 API 标准对于构建可扩展、高效的系统至关重要。Java 在现代 API 方面以其在企业应用中的稳定性而闻名,不断适应这些现代范式的需求。随着不断发展的生态系统,Java 在现代 API 方…...
