从单数据源到多数据源的探讨

news/2025/1/18 16:20:10/文章来源:https://www.cnblogs.com/guoxiaoyu/p/18676914

今天我想简单地分享一下如何将一个老项目从单数据源切换为多数据源的过程。这个项目是一个使用 WAR 部署的传统 JSP Web 项目,运行在 JDK 1.7 环境下,项目中并没有使用 Spring Boot,而仅仅采用了 Spring MVC 框架。我的主要任务是将原本使用单一数据源的架构,升级为支持多数据源的架构。

为此,首先需要梳理清楚当前项目的模块依赖和数据源的使用情况,了解项目中所有的模块和类是如何引用和交互的,特别是涉及到数据库操作的部分。

引用排查

我也很直接,直接找到datasource关键字直接全局搜索,找到了很多引用地方,有些确实是命名不是很规范,并不是数据源也起名叫了这个名字,第一步直接去除没有用的相关类,做一个简单的筛除。如图所示:

image

接下来,我将剩余的引用部分划分为三个主要部分,具体如下:第一部分是与XML配置相关的内容。由于该项目是一个较为传统的Spring MVC老项目,因此所有的Bean依赖关系都是在XML文件中显式配置的。这一部分的工作主要是分析和梳理XML配置文件中与Bean定义及依赖注入相关的内容。

第二部分是Java引用的相关内容。对于一些XML中配置好的Bean,这些配置会被注入到Java类的相应位置,并在运行时使用。因此,这一部分需要重点关注那些通过XML配置注入的Bean以及它们在Java代码中的应用场景。

最后第三部分是关于properties配置文件的检查。需要检查是否有单独的配置项存在于properties文件中,这些配置项可能会影响系统的某些行为或参数设置。

业务梳理

这部分不太好说,需要自己对整个项目有所掌握才可以,要不然会让自己看的头疼,这部分看的时候,大概想了一下为什么这里这么用,这里用到数据源做了哪些业务,如果切换成多数据源后,应该如何处理。

我大概看了一下有基本下面几种情况:

  1. 注入数据源,直接生成jdbctemplate对象后,在代码里写业务逻辑执行SQL,看的头疼~~
  2. 注入到sqlsessionfactorybean中,集成到mybatis中。
  3. 使用现成的spring-security,注入数据源后,直接查询各种权限信息。
  4. 国际化配置使用到了数据源信息。

目前就这几种,因为项目使用的是jndi的方式注入,所以对于多数据源来说也有一些困难。不过我的大概思路就是将数据源注入个默认数据源,使用动态key的方式切换数据源。

后期思路

比如,配置文件首先就需要有多个数据源的信息,如下所示:

<bean id="dataSource1" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"><property name="driverClassName" value="com.mysql.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/db1"/><property name="username" value="user1"/><property name="password" value="pass1"/>
</bean><bean id="dataSource2" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"><property name="driverClassName" value="com.mysql.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/db2"/><property name="username" value="user2"/><property name="password" value="pass2"/>
</bean><bean id="sqlSessionFactory" class="ReloadableSqlSessionFactoryBean"><property name="targetDataSources"><map key-type="java.lang.String"><entry key="dataSource1" value-ref="dataSource1"/><entry key="dataSource2" value-ref="dataSource2"/></map></property>
</bean>

定义数据源路由

public class DataSourceContextHolder {private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();public static void setDataSourceKey(String key) {contextHolder.set(key);}public static String getDataSourceKey() {return contextHolder.get();}public static void clearDataSourceKey() {contextHolder.remove();}
}

配置动态数据源

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;public class DynamicDataSource extends AbstractRoutingDataSource {@Overrideprotected Object determineCurrentLookupKey() {return DataSourceContextHolder.getDataSourceKey();}
}

集成到SqlSessionFactoryBean,在 ReloadableSqlSessionFactoryBean 中使用动态数据源:

public class MySqlSessionFactoryBean extends SqlSessionFactoryBean implements DisposableBean {private static final Log log = LogFactory.getLog(MySqlSessionFactoryBean.class);private AbstractRoutingDataSource routingDataSource;public void setTargetDataSources(Map<Object, Object> targetDataSources) {if (routingDataSource == null) {routingDataSource = new DynamicDataSource();}routingDataSource.setTargetDataSources(targetDataSources);routingDataSource.setDefaultTargetDataSource(targetDataSources.values().iterator().next());super.setDataSource(routingDataSource);}@Overrideprotected SqlSessionFactory buildSqlSessionFactory() throws Exception {return super.buildSqlSessionFactory();}@Overridepublic void destroy() throws Exception {// 清理资源}
}

在需要切换数据源的地方调用 DataSourceContextHolder.setDataSourceKey("dataSource1") 或 DataSourceContextHolder.setDataSourceKey("dataSource2")。

总的来说,将传统单数据源架构迁移到多数据源架构并不简单,但通过合理的模块梳理和逐步推进,整个过程可以得到有效实施。

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

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

相关文章

eclipse thymeleaf 离线安装

下载zip包 https://github.com/thymeleaf/thymeleaf-extras-eclipse-plugin/releases 选择zip包参考 https://www.cnblogs.com/jiduoduo/p/15525430.html

Cisco ISR 1000 Series IOS XE Release 17.16.1a ED

Cisco ISR 1000 Series IOS XE Release 17.16.1a EDCisco ISR 1000 Series IOS XE Release 17.16.1a ED 思科 1000 系列集成多业务路由器 IOS XE 系统软件 请访问原文链接:https://sysin.org/blog/cisco-isr-1000/ 查看最新版。原创作品,转载请保留出处。 作者主页:sysin.or…

Cisco ISR 4000 Series IOS XE Release 17.16.1a ED

Cisco ISR 4000 Series IOS XE Release 17.16.1a EDCisco ISR 4000 Series IOS XE Release 17.16.1a ED 思科 4000 系列集成服务路由器 IOS XE 系统软件 请访问原文链接:https://sysin.org/blog/cisco-isr-4000/ 查看最新版。原创作品,转载请保留出处。 作者主页:sysin.org思…

卷积运算

对应位置数字相乘,求和。卷积核(或滤波器)的小窗口在输入数据上滑动,计算窗口覆盖区域的元素乘积之和,从而生成输出数据。 二维卷积 运算 1x7 + 2x6 + 3x5 + 4x4 = 50 1x6 + 2x2 + 3x4 + 4x2 = 30 彩色图像卷积运算; R 卷积运算 对应位置 乘积求和; G-green 绿色…

linux实现macos的timeMachine系统备份

在上一篇文章中,我们详细介绍了Btrfs文件系统的基本使用方法和核心原理。本文将重点讲解如何利用Btrfs的特性来实现系统备份功能。 实现原理其实很简单:Linux内核支持直接从Btrfs的子卷(subvolume)启动系统。基于这个特性,我们可以通过计划任务定期为系统根目录创建快照,…

btrfs文件系统从原理到实践 [1]

作为Linux用户,我经常羡慕macOS系统的Time Machine功能。Time Machine就像是系统的最后一道防线,无论系统发生什么变化,它都能保护我们的数据安全,避免因误操作导致系统无法启动的困境。那么,Linux系统下是否也有类似的解决方案呢?基于这样的需求,我发现了Btrfs文件系统…

常用图像增强算法(MATLAB实现)

1 引言 图像增强是指按照某种特定的需求,突出图像中有用的信息,去除或者削弱无用的信息。图像增强的目的是使处理后的图像更适合人眼的视觉特性或者易于机器识别。在医学成像、遥感成像、人物摄影等领域,图像增强技术都有着广泛的应用。图像增强同时可以作为目标识别,目标跟…

【PE文件结构】导入表

导入表(Import Table)是Windows可执行文件中的一部分,它记录了程序所需调用的外部函数(或API)的名称,以及这些函数在哪些动态链接库(DLL)中可以找到。在PE文件运行过程需要依赖哪些模块,以及依赖这些模块中的哪些函数,这些信息就记录在导入表中。在Win32编程中我们会…

ciscn_2019_es_2(栈迁移)

看一下ida两个read函数都是读取0x30(48),然后s距离ebp有0x28(40),所以虽然有溢出但只溢出了两个4字节,也就是只能覆盖到ebp和ret。 这时候就需要运用栈迁移 栈迁移就是当溢出不够多的时候,这时候可以考虑把栈给迁移去其它地方,利用leave_ret指令控制ebp,使其指向我们…

Nexpose 7.3.0 for Linux Windows - 漏洞扫描

Nexpose 7.3.0 for Linux & Windows - 漏洞扫描Nexpose 7.3.0 for Linux & Windows - 漏洞扫描 Rapid7 on-prem Vulnerability Management, released Jan 15, 2025 请访问原文链接:https://sysin.org/blog/nexpose-7/ 查看最新版。原创作品,转载请保留出处。 作者主页…

ABB机器人3HNE00313-1示教器黑屏故障维修

随着工业自动化的快速发展,ABB机器人示教器在生产线上的应用越来越广泛。然而,在使用过程中,示教器偶尔也会出现故障,其中比较常见的一种是ABB工业机械手示教器黑屏故障。 一、ABB工业机器人示教盒黑屏故障原因分析 1. 硬件故障:硬件故障是导致示教器黑屏的主要原因之一。…

windows双击查看ip

如何方便查看本地电脑的ip? 直接上干货: 1、在桌面右击,新建 => 文本文档; 2、重命令为ip.txt 3、双击打开,输入 ipconfig pause , 然后保存; 4、右击文档,重命令为“ip.bat”;5、再次双击此文档,ip地址就出来了; ps: ipconfig:是系统命令,用于查看ip的地址…