当前位置: 首页 > 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…...

浅尝Appium自动化框架

浅尝Appium自动化框架 Appium自动化框架介绍Appium原理Appium使用安装平台驱动实战 坑 Appium自动化框架介绍 Appium 是一个开源的自动化测试框架&#xff0c;最初设计用于移动应用的测试&#xff0c;但现在它也扩展了对桌面端应用的支持。Appium 使得自动化测试变得更加简单&…...

网络安全测评技术与标准

网络安全测评概况 网络安全测评是网络信息系统和IT技术产品的安全质量保障。本节主要阐述网络安全测评的概念&#xff0c;给出网络安全测评的发展状况。 18.1.1 网络安全测评概念 网络安全测评是指参照一定的标准规范要求&#xff0c;通过一系列的技术和管理方法&#xff0c;获…...

【经典神经网络架构解析篇】【1】LeNet网络详解:模型结构解析、优点、实现代码

《------往期经典推荐------》 一、AI应用软件开发实战专栏【链接】 项目名称项目名称1.【人脸识别与管理系统开发】2.【车牌识别与自动收费管理系统开发】3.【手势识别系统开发】4.【人脸面部活体检测系统开发】5.【图片风格快速迁移软件开发】6.【人脸表表情识别系统】7.【…...

KGA:AGeneral Machine Unlearning Framework Based on Knowledge Gap Alignment

文章目录 摘要1 引言2 相关工作3 符号与定义4 我们的 KGA 框架4.1 KGA框架知识差距对齐目标 4.2 KGA在自然语言处理任务中的应用文本分类机器翻译响应生成 5 实验设置数据集评估指标参数设置比较方法 6 实验结果6.1 主要比较结果6.2 KGA 的优越性分析降低语言模型概率比较 6.3 …...

GelSight Mini视触觉传感器凝胶触头升级:增加40%耐用性,拓展机器人与触觉AI 应用边界

马萨诸塞州沃尔瑟姆-2025年1月6日-触觉智能技术领军企业Gelsight宣布&#xff0c;旗下Gelsight Mini视触觉传感器迎来凝胶触头的更新。经内部测试&#xff0c;新Gel凝胶触头耐用性提升40%&#xff0c;外观与触感与原凝胶触头保持一致。此次升级有效满足了客户在机器人应用中对设…...

springboot整合admin

1. 添加依赖 首先&#xff0c;在你的admin服务端pom.xml文件中添加Spring Boot Admin的依赖&#xff1a; <dependency><groupId>de.codecentric</groupId><artifactId>spring-boot-admin-starter-server</artifactId><version>2.5.4<…...

OS--常见的网络模型(包含IO多路复用的原理)

网络模型 IO模型主要就是用户空间和内核空间数据交换的形式。 IO模型 阻塞 I/O 模型&#xff08;Blocking I/O&#xff09; 应用程序发起 I/O 请求后&#xff0c;会被阻塞&#xff0c;直到 I/O 操作完成。 非阻塞 I/O 模型&#xff08;Non-blocking I/O&#xff09; 应用程序…...

LCE(Local Cascade Ensemble)预测模型和LSTM(Long Short-Term Memory)模型在效果和特点上存在显著差异

LCE&#xff08;Local Cascade Ensemble&#xff09;预测模型和LSTM&#xff08;Long Short-Term Memory&#xff09;模型在效果和特点上存在显著差异。以下是对两者的比较&#xff1a; 一、效果比较 LCE模型&#xff1a; 优势&#xff1a;LCE结合了随机森林和XGBoost的优势&a…...

【mysql】约束的基本使用

文章目录 1. PRIMARY KEY 约束1.1 作用1.2 关键字1.3 特点1.4 添加主键约束1.5 关于复合主键1.6 删除主键约束 2. 自增列&#xff1a;AUTO_INCREMENT2.1 作用2.2 关键字2.3 特点和要求2.4 如何指定自增约束2.5 如何删除自增约束2.6 MySQL 8.0新特性—自增变量的持久化 3. FOREI…...

EasyExcel(二)导出Excel表自动换行和样式设置

EasyExcel(一)导出Excel表列宽自适应 背景 在上一篇文章中解决导出列宽自适应,然后也解决了导出列宽不可超过255的问题。但是实际应用场景中仍然会有导出数据的长度超过列宽255。这时导出效果就会出现如下现象: 多出列宽宽度的内容会浮出来,影响后边列数据的显示。 解决…...

郑州网站模板建设/免费b站推广网址有哪些

目录 译序获取代码关于兼容性的提醒Visual Studio下安装Xcode下安装Linux下安装GLEW, GLFW和GLM介绍什么是Shaders&#xff1f;Vertex ShadersFragment Shaders编译和链接Shaders什么是VBO和VAO&#xff1f;Vertex Buffer Objects (VBOs)Vertex Array Objects (VAOs)代码解释进…...

民权做网站哪家好/上海网络seo公司

你有被朋友圈掀起的python热“烫到”了吗&#xff1f;之前我就被朋友圈的一则python广告惊到了&#xff01;今天见到这个广告的点赞评论依旧那么多&#xff01;热度丝毫没有要减的意思(目瞪口呆.jpg)朋友圈里编辑、运营、HR、市场、医生、行政……那些本和技术八竿子打不着关系…...

江苏省建筑网站/网站友情链接有什么用

1、MyBatis是什么&#xff1f; MyBatis源自于IBatis&#xff0c;是一个持久层框架&#xff0c;封装了jdbc操作数据库的过程&#xff0c;使得开发者只用关心sql语句&#xff0c;无需关心驱动加载、连接&#xff0c;创建statement&#xff0c;手动设置参数&#xff0c;结果集检索…...

网站建设公司发展/最近一两天的新闻有哪些

至少,您需要三个类&#xff1a;一个用于表示数据,一个用于UI,另一个用于管理数据库连接.当然,在真正的应用程序中,您需要的不仅仅是这个.此示例遵循与TableView tutorial相同的基本示例假设您的数据库有一个包含三列的person表,first_name,last_name,email_address.然后你会写一…...

网站开发需要学多久/谷歌推广开户多少费用

选择排序(Selection sort&#xff09;跟插入排序一样&#xff0c;也是O(n^2)的复杂度&#xff0c;这个排序方式也可以用我们的扑克牌来解释。 概念 桌面上有一堆牌&#xff0c;也是杂乱无章的&#xff0c;现在我们想将牌由小到大排序&#xff0c;如果使用选择排序来做&#xff…...

深圳外贸soho网站建设/百度一下你就知道下载安装

2019独角兽企业重金招聘Python工程师标准>>> 占位 转载于:https://my.oschina.net/macthink/blog/384601...