【Spring Boot】Spring Boot整合多数据源

文章目录

  • 前言
  • 一、基本概念
    • 1.1 什么是多数据源?
    • 1.2 为什么要使用多数据源?
  • 二、如何在 Spring Boot 中整合多数据源?
    • 2.1 基本配置
    • 2.2 项目代码
    • 2.3 注意事项

前言

在实际的开发工作中,我们经常会遇到需要整合多个数据源的情况,比如同时连接多个数据库、读写分离、跨数据库查询等。本文将介绍如何使用Spring Boot来实现多数据源的整合,对于刚刚接触开发的小伙伴可能有一些帮助。

一、基本概念

1.1 什么是多数据源?

在一个应用程序中使用多个数据源意味着我们需要在不同的数据源之间进行切换,以便从不同的数据源中获取数据。多数据源可以是关系数据库、NoSQL 数据库、平面文件、XML 文件等。在一个应用程序中使用多数据源的好处是,我们可以根据应用程序的需求选择最合适的数据源,从而提高应用程序的性能和可扩展性。

1.2 为什么要使用多数据源?

在一个应用程序中使用多数据源的好处有很多,其中一些是:

  • 可以根据应用程序的需求选择最合适的数据源,从而提高应用程序的性能和可扩展性。
  • 可以减少单一数据源所带来的风险,例如单点故障。
  • 可以更好地支持数据的隔离和数据的安全性。
  • 可以更好地支持不同的业务需求。

二、如何在 Spring Boot 中整合多数据源?

2.1 基本配置

接下来的整合示例,我将以实际项目整合示例来介绍,项目中是mysql和phoenix多数据源,那么接下来详细描述一下,因为项目中整合了MybatisPlus,所以也会有一些相关的配置,首先,我们需要在pom.xml文件中添加相应的依赖项。以下是常用的数据源依赖项:

<!-- 数据源 -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!-- MySQL 数据库 -->
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- phoenix 数据库 -->
<dependency><groupId>org.apache.phoenix</groupId><artifactId>phoenix-core</artifactId>
</dependency>
<!-- mybatis-plus -->
<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId>        
</dependency>

接下来,我们需要在application.properties或application.yml文件中配置各个数据源的连接信息。以下是示例配置:

 #数据库配置datasource:#mysql数据源配置mysql:type: com.zaxxer.hikari.HikariDataSourcejdbc-url: jdbc:p6spy:mysql://xxxx:3306/xxxx?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=trueusername: xxxxpassword: xxxxx# Hikari 连接池配置# 最小空闲连接数量hikari:minimum-idle: 5# 空闲连接存活最大时间,默认600000(10分钟)idle-timeout: 180000# 连接池最大连接数,默认是10maximum-pool-size: 10# 此属性控制从池返回的连接的默认自动提交行为,默认值:trueauto-commit: true# 连接池名称pool-name: xxxx-HikariCP# 此属性控制池中连接的最长生命周期,值0表示无限生命周期,默认1800000即30分钟max-lifetime: 1800000# 数据库连接超时时间,默认30秒,即30000connection-timeout: 30000connection-test-query: SELECT 1#phoenix数据源配置phoenix:driver: org.apache.phoenix.jdbc.PhoenixDriverjdbcUrl: jdbc:phoenix:xxxxx:xxxxuser:password:connectionProperties:isNamespaceMappingEnabled: truemapSystemTablesToNamespace: trueschema: 'xxxxxx'maximumPoolSize: 128maxLifetime: 1200000

之后,我们需要创建多个数据源的配置类,以及一些基础的配置。以下是示例代码:

@EnableTransactionManagement
@Configuration
@MapperScan("com.xxxx.mapper")
public class DataSourceConfig {@Autowiredprivate PhoenixProperties phoenixProperties;@Beanpublic PaginationInterceptor paginationInterceptor() {return new PaginationInterceptor().setDialectType("mysql");}@Bean(name = "mysqlDateSource")@ConfigurationProperties(prefix = "spring.datasource.mysql")public HikariDataSource mysqlDateSource() {return DataSourceBuilder.create().type(HikariDataSource.class).build();}@Bean(name = "phoenixDataSource")public HikariDataSource phoenixDataSource() {HikariDataSource dataSource = new HikariDataSource();dataSource.setDriverClassName(phoenixProperties.getDriver());dataSource.setJdbcUrl(phoenixProperties.getJdbcUrl());dataSource.setUsername(phoenixProperties.getUser());dataSource.setPassword(phoenixProperties.getPassword());Properties properties = new Properties();properties.setProperty("phoenix.schema.isNamespaceMappingEnabled", phoenixProperties.getIsNamespaceMappingEnabled());properties.setProperty("phoenix.schema.mapSystemTablesToNamespace", phoenixProperties.getMapSystemTablesToNamespace());properties.setProperty("schema", phoenixProperties.getSchema());properties.setProperty("maximum-pool-size", phoenixProperties.getMaximumPoolSize());properties.setProperty("max-lifetime", phoenixProperties.getMaxLifetime());dataSource.setDataSourceProperties(properties);return dataSource;}/*** 动态数据源配置** @return DataSource*/@Bean@Primarypublic DataSource multipleDataSource(@Qualifier("mysqlDateSource") DataSource mysqlDateSource, @Qualifier("phoenixDataSource") DataSource phoenixDataSource) {MultipleDataSource multipleDataSource = new MultipleDataSource();Map<Object, Object> targetDataSources = Maps.newHashMap();targetDataSources.put(DataSourceEnum.MYSQL.getValue(), mysqlDateSource);targetDataSources.put(DataSourceEnum.PHOENIX.getValue(), phoenixDataSource);//添加数据源multipleDataSource.setTargetDataSources(targetDataSources);//设置默认数据源multipleDataSource.setDefaultTargetDataSource(mysqlDateSource);return multipleDataSource;}@Bean(name = "sqlSessionFactory")public SqlSessionFactory sqlSessionFactory() throws Exception {MybatisSqlSessionFactoryBean sqlSessionFactory = new MybatisSqlSessionFactoryBean();sqlSessionFactory.setDataSource(multipleDataSource(mysqlDateSource(), phoenixDataSource()));ResourceLoader loader = new DefaultResourceLoader();String resource = "classpath:mybatis-config.xml";sqlSessionFactory.setConfigLocation(loader.getResource(resource));ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();sqlSessionFactory.setMapperLocations(resolver.getResources("classpath*:/mapper/*.xml"));sqlSessionFactory.setTypeAliasesPackage("com.huitongjy.oms.web.entity");sqlSessionFactory.setTypeEnumsPackage("com.huitongjy.oms.common.enums");//关键代码 设置 MyBatis-Plus 分页插件Interceptor[] plugins = {paginationInterceptor()};sqlSessionFactory.setPlugins(plugins);return sqlSessionFactory.getObject();}}

MultipleDataSource类

public class MultipleDataSource extends AbstractRoutingDataSource {@Overrideprotected Object determineCurrentLookupKey() {return DataSourceContextHolder.getDataSource();}
}class DataSourceContextHolder {private static final ThreadLocal<String> CONTEXT_HOLDER = new InheritableThreadLocal<>();/*** 设置数据源** @param db String*/static void setDataSource(String db) {CONTEXT_HOLDER.set(db);}/*** 取得当前数据源** @return String*/static String getDataSource() {return CONTEXT_HOLDER.get();}/*** 清除上下文数据*/static void clear() {CONTEXT_HOLDER.remove();}
}

mybatis-config.xml的配置如下:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><settings><setting name="cacheEnabled" value="false"/><setting name="lazyLoadingEnabled" value="true"/><setting name="multipleResultSetsEnabled" value="true"/><setting name="useColumnLabel" value="true"/><setting name="useGeneratedKeys" value="false"/><setting name="autoMappingBehavior" value="PARTIAL"/><setting name="autoMappingUnknownColumnBehavior" value="WARNING"/><setting name="defaultExecutorType" value="SIMPLE"/><setting name="defaultStatementTimeout" value="25"/><setting name="defaultFetchSize" value="100"/><setting name="safeRowBoundsEnabled" value="false"/><setting name="mapUnderscoreToCamelCase" value="true"/><setting name="localCacheScope" value="SESSION"/><setting name="jdbcTypeForNull" value="OTHER"/><setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/></settings>
</configuration>

在上面的代码中,我们使用 @ConfigurationProperties(prefix = “spring.datasource.mysql”) 将配置文件中的属性绑定到 mysql 的 HikariDataSource 对象上。同样地,我们也为 phoenixDataSource 进行绑定。
这两个数据源分别连接不同的数据库。@Primary注解表示主要的数据源,用于在运行时决定使用哪个数据源。我们创建了一个名为multipleDataSource的方法,该方法添加数据源,并且设置好默认的数据源,
最后,在SqlSessionFactory加载多数据源,以及一些配置文件,这样就可以管理和配置数据库连接。

2.2 项目代码

配置完之后,我们只需要在phoenix接口上配置一下数据源即可,代码如下:

public interface TestDetailMapper {/*** 保存* @param testDetail*/@DataSource(DataSourceEnum.PHOENIX)@Insert(" upsert into xxx_xxx (xxxxx) " +" values (#{xxxx})")void insert(@Param("xxx") TestDetail testDetail);/*** 获取内容** @param xxxx* @return xxx*/@Results(value = {@Result(property = "xxxx", column = "xxxxx")})@DataSource(DataSourceEnum.PHOENIX)@Select("SELECT XXXX FROM XXX WHERE XXX=#{XXXX}")TestDetail findByKey(@Param("XXXX") String XXXX);}

通过上述代码,我们已经成功实现了多数据源的整合。

2.3 注意事项

(1)必须指定主数据源,就是在主数据源的bean注入上加一个@Primary注解,表示同一个类的多个对象注入,优先选择有注解@Primary的对象。
(2)不同数据源的dao和mapper文件最好分开到不同包路径和文件路径下,这样才能单独的配置文件映射,不然会出错。

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

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

相关文章

Nginx使用keepalived配置VIP

VIP常用于负载均衡的高可用&#xff0c;使用VIP可以给多个主机绑定一个IP&#xff0c;这样&#xff0c;当某个负载应用挂了之后&#xff0c;可以自动切到另一个负载。 我这里是在k8s环境中做的测试&#xff0c;集群中有6个节点&#xff0c;我给140和141两个节点配置VIP。 1. 安…

Python土力学与基础工程计算.PDF-压水试验

Python 求解代码如下&#xff1a; 1. import math 2. 3. # 输入参数 4. L 2.0 # 试验段长度&#xff0c;m 5. Q 120.0 # 第三阶段计算流量&#xff0c;L/min 6. p 1.5 # 第三阶段试验段压力&#xff0c;MPa 7. r0 0.05 # 钻孔半径&#xff0c;m 8. 9. # 计算透…

Docker 微服务实战

1. 通过IDEA新建一个普通微服务模块 1.1 建Module docker_boot 1.2 改写pom <?xml version"1.0" encoding"UTF-8"?><project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance&…

CDN、DNS、ADN、SCDN、DCDN、ECDN、PCDN、融合CDN傻傻分不清楚,一文全部搞懂

一、CDN是什么&#xff1f; CDN的全称是Content Delivery Network&#xff0c;即内容分发网络。其基本思路是尽可能避开互联网上有可能影响数据传输速度和稳定性的瓶颈和环节&#xff0c;使内容传输得更快、更稳定。通过在网络各处放置节点服务器所构成的在现有的互联网基础之…

1267. 统计参与通信的服务器

这里有一幅服务器分布图&#xff0c;服务器的位置标识在 m * n 的整数矩阵网格 grid 中&#xff0c;1 表示单元格上有服务器&#xff0c;0 表示没有。 如果两台服务器位于同一行或者同一列&#xff0c;我们就认为它们之间可以进行通信。 请你统计并返回能够与至少一台其他服务…

算法练习(9):牛客在线编程09 双指针

package jz.bm;import jz.Interval;import java.util.ArrayList; import java.util.HashMap;public class bm9 {/*** BM87 合并两个有序的数组*/public void merge(int A[], int m, int B[], int n) {int i m - 1, j n - 1, k m n - 1;while (i > 0 || j > 0) {int a…

我是如何使用Spring Retry减少1000 行代码

使用 Spring Retry 重构代码的综合指南。 问题介绍 在我的日常工作中&#xff0c;我主要负责开发一个庞大的金融应用程序。当客户发送请求时&#xff0c;我们使用他们的用户 ID 从第三方服务获取他们的帐户信息&#xff0c;保存交易并更新缓存中的详细信息。尽管整个流程看起来…

Elasticsearch简介及安装

&#x1f353; 简介&#xff1a;java系列技术分享(&#x1f449;持续更新中…&#x1f525;) &#x1f353; 初衷:一起学习、一起进步、坚持不懈 &#x1f353; 如果文章内容有误与您的想法不一致,欢迎大家在评论区指正&#x1f64f; &#x1f353; 希望这篇文章对你有所帮助,欢…

H36M VS 3DPW datasets

1采集设备方面 H36M使用了高精度的多视角摄像机动态捕捉系统获得了非常准确和连贯的3D关节坐标标注。 3DPW使用了单目摄像机与IMU的复合传感系统进行采集,存在一定程度的标注噪声。 2场景环境方面 H36M主要针对室内定向动作,背景单一简洁。 3DPW重点是室外复杂环境中人的自…

Interlij IDEA 运行 ruoyi 后端项目。错误: 找不到或无法加载主类 com.ruoyi.auth.RuoYiAuthApplication

错误: 找不到或无法加载主类 com.ruoyi.auth.RuoYiAuthApplication 用了 IDEA运行&#xff0c;参考以下issue删除.idea目录也没有用 (官方文档写是用Eclipse运行&#xff09; 错误: 找不到或无法加载主类 com.ruoyi.auth.RuoYiAuthApplication Issue #I48N2X 若依/RuoYi-C…

前端:运用html+css+jquery.js实现截图游戏

前端:运用htmlcssjquery.js实现截图游戏 1. 前言2. 实现原理3. 参考代码和运行结果 1. 前言 最近在刷手机视频时&#xff0c;总是能刷到一个这样的视频&#xff0c;视频上是一个截图游戏&#xff0c;当图片上的某个片段正好在图片的正确位置时&#xff0c;暂停视频&#xff0c;…

回归预测 | MATLAB实现FA-ELM萤火虫算法优化极限学习机多输入单输出回归预测(多指标,多图)

回归预测 | MATLAB实现FA-ELM萤火虫算法优化极限学习机多输入单输出回归预测&#xff08;多指标&#xff0c;多图&#xff09; 目录 回归预测 | MATLAB实现FA-ELM萤火虫算法优化极限学习机多输入单输出回归预测&#xff08;多指标&#xff0c;多图&#xff09;效果一览基本介绍…

Powershell NTP Server Windows 7,8,10,11,2012,2016,2019,2022

NTP前言 NTP服务器是用来使计算机时间同步化的一种协议,它可以使计算机对其服务器或时钟源(如石英钟、GPS等)做同步化,提供高精准度的时间校正(LAN上与标准间差小于1毫秒,WAN上几十毫秒),且可介由加密确认的方式来防止恶毒的协议1。 ntp 参考 w32tmpowershell参考 参考…

宠物赛道,用AI定制宠物头像搞钱项目教程

今天给大家介绍一个非常有趣&#xff0c;而粉丝价值又极高&#xff0c;用AI去定制宠物头像或合照的AI项目。 接触过宠物行业应该知道&#xff0c;获取1位铲屎官到私域&#xff0c;这类用户的价值是极高的&#xff0c;一个宠物粉&#xff0c;是连铲个屎都要花钱的&#xff0c;每…

怎样压缩mp4视频大小?

怎样压缩mp4视频大小&#xff1f;由于视频文件的体积通常比其他类型的文件更大&#xff0c;因此它们需要更多的存储空间来保存。但是&#xff0c;如果我们的设备、应用程序或平台不支持某些视频格式或分辨率&#xff0c;或者我们没有足够的存储空间来容纳这些大型视频文件&…

测试平台metersphere

metersphere可以做接口测试、UI测试、性能测试。 metersphere接口测试底层是jmeter&#xff0c;可以做API管理&#xff0c;快捷调试&#xff0c;接口用例管理&#xff0c;接口自动化场景执行一键选取用例范围&#xff0c;生成测试报告。 会用jmeter&#xff0c;metersphere会…

服务器能运行什么应用

服务器能运行什么应用 服务器是一种应用范围很广的网络技术产品&#xff0c;它在影视、视频以及医疗和金融等多个领域&#xff0c;都可以发挥使用价值&#xff0c;那么服务器能运行什么应用?大家跟着壹基比小鑫一起来了解吧&#xff01; 服务器的作用是什么&#xff1f; 服…

【Unity小技巧】最简单的UI设置适配方案,萌新必看

文章目录 前言导入素材开始一、页面适配方案二、侧边栏适配方法一方法二 参考完结 前言 这期来讲一个简单的UI设计方案&#xff0c;很多同学可能搞不懂锚点、轴心这些概念&#xff0c;导致做好的UI在别人的设备上&#xff0c;乱跑或者是重叠&#xff0c;或者是参加游戏老发时间…

自然语言处理在智能客服和聊天机器人中的应用

文章目录 1. 引言2. NLP基础2.1 词法分析2.2 语法分析2.3 语义理解2.4 情感分析 3. 智能客服中的应用3.1 自动问答3.2 意图识别3.3 情感分析与情绪识别 4. 聊天机器人中的应用4.1 对话生成4.2 上下文理解 5. 技术原理与挑战5.1 语言模型5.2 数据质量和多样性5.3 上下文理解 6. …

线性代数的学习和整理5: 矩阵的加减乘除及其几何意义

目录 1 矩阵加法 1.1 矩阵加法的定义 1.2 加法的属性 1.2.1 只有同类型&#xff0c;相同n*m的矩阵才可以相加 1.2.1 矩阵加法的可交换律&#xff1a; 1.2.2 矩阵加法的可结合律&#xff1a; 1.3矩阵加法的几何意义 2 矩阵的减法 2.1 矩阵减法定义和原理基本同 矩阵的…