首页 > 其他分享 >从单数据源到多数据源的探讨

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

时间:2025-01-18 16:21:48浏览次数:1  
标签:XML 数据源 配置 探讨 public static routingDataSource 从单

今天我想简单地分享一下如何将一个老项目从单数据源切换为多数据源的过程。这个项目是一个使用 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 {
    @Override
    protected 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);
    }

    @Override
    protected SqlSessionFactory buildSqlSessionFactory() throws Exception {
        return super.buildSqlSessionFactory();
    }

    @Override
    public void destroy() throws Exception {
        // 清理资源
    }
}

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

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

标签:XML,数据源,配置,探讨,public,static,routingDataSource,从单
From: https://www.cnblogs.com/guoxiaoyu/p/18676914

相关文章

  • 【Python】深入探讨Python中的单例模式:元类与装饰器实现方式分析与代码示例
    《PythonOpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门!解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界单例模式(SingletonPattern)是一种常见的设计模式,它确保一个类只有一个实例,并提供一个全局访问点。在Python中,实现单例模式的方式多种多样,包括......
  • 探讨c++内存布局背后的原因以及策略
    内存布局通常是按照成员变量的声明顺序,但由于对齐和填充的影响,编译器可能会调整成员变量的顺序。改变顺序的主要目的是为了优化内存使用和提高访问效率。以下是一些具体原因:1.提高内存访问效率对齐要求:不同数据类型有不同的对齐要求。将对齐要求相同或相近的成员变量放......
  • springboot环境下的rokectMQ多数据源实现
    业务原因,需要在一个项目中与多方MQ进行业务通信;步骤一,复制一份RocketMQProperties配置文件,避免与原来的冲突packagecom.heit.road.web.config;importorg.apache.rocketmq.common.topic.TopicValidator;importjava.util.HashMap;importjava.util.Map;publicclassMu......
  • DevExpress gridControl 绑定数据源之后添加非绑定列
    using(DevExpress.Utils.WaitDialogFormdlg=newDevExpress.Utils.WaitDialogForm("请稍等","查询中......",newSystem.Drawing.Size(100,50))){stringsqlString="SELECTITEM,DESCRIPTION,CATEGORY3FROMW......
  • 深入探讨聚合函数(COUNT, SUM, AVG, MAX, MIN):分析和总结数据的新视野
    title:深入探讨聚合函数(COUNT,SUM,AVG,MAX,MIN):分析和总结数据的新视野date:2025/1/13updated:2025/1/13author:cmdragonexcerpt:在数据分析和数据库管理领域,聚合函数(AggregateFunctions)是获取数据总结和统计信息的关键工具。聚合函数如COUNT、SUM、AVG、M......
  • 深入探讨聚合函数(COUNT, SUM, AVG, MAX, MIN):分析和总结数据的新视野
    title:深入探讨聚合函数(COUNT,SUM,AVG,MAX,MIN):分析和总结数据的新视野date:2025/1/13updated:2025/1/13author:cmdragonexcerpt:在数据分析和数据库管理领域,聚合函数(AggregateFunctions)是获取数据总结和统计信息的关键工具。聚合函数如COUNT、SUM、AVG、M......
  • 探讨人工智能机器人学之路径规划与导航:A*算法、Dijkstra算法等路径规划方法
    引言在人工智能(AI)和机器人学中,路径规划与导航是一个至关重要的课题。机器人在复杂的环境中,必须能够根据环境信息和目标要求,自动计算一条从起始位置到目标位置的最优或可行的路径。路径规划不仅仅是关于如何找到目标位置,还涉及如何在多变、动态的环境中避免障碍、实现效率和安......
  • 优质内容在个人IP运营中的重要性:以开源AI智能名片商城小程序为应用实例的深度探讨
    摘要:在数字化时代,个人品牌(IP)的塑造与传播已成为各行各业提升影响力、吸引用户关注、促进商业转化的关键策略。优质内容作为连接个人IP与目标受众的桥梁,其在个人IP运营中的重要性不言而喻。本文旨在深入探讨优质内容在个人IP运营中的核心价值,并结合“开源AI智能名片商城小程序”......
  • 【DNS攻防】深入探讨DNS数据包注入与DNS中毒攻击检测 (C/C++代码实现)
    DNS数据包注入和DNS中毒攻击是网络安全领域中的两个重要主题。DNS(域名系统)是互联网中的一项核心服务,负责将域名转换为与之相对应的IP地址。DNS数据包注入是指攻击者通过篡改或伪造DNS请求或响应数据包来干扰或破坏DNS服务的过程。攻击者可通过注入恶意数据包来改变DNS解析结果,将......
  • dolphinscheduler 创建 mssql 数据源失败解决
    解决方法:在参数处加入{"encryp":"false","trustServerCertificate":"true"}现象:[ERROR]2025-01-1110:44:36.821+0800org.apache.dolphinscheduler.plugin.datasource.api.datasource.AbstractDataSourceProcessor:[124]-Checkdataso......