java通过JdbcTemplate连接多个(2个以上)不同类型的数据库

2023-11-02

1、业务场景

要求获取不同数据库的表信息和表结构信息,数据库类型包括oracle,MySQL,SqlServer。

2、实现思路

step1 新增数据库连接信息(主机,端口,数据库类型,实例名,用户名,密码,状态)

step2 测试连接,成功状态正常,失败不正常

step3 创建JdbcTemplate对象,保存到map中(key=唯一标识符,value=JdbcTemplate对象),避免重复创建销毁

step4 通过SQL语句获取表信息和表结构

step5定时检查map,销毁不常用的JdbcTemplate对象

3、代码

工厂类生成JdbcTemplate对象。

package com.aadata.etl.cache;

import com.aadata.etl.model.DbConnInfo;
import com.aadata.etl.util.DateUtil;
import com.aadata.etl.util.StringUtil;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.sql.DataSource;
import java.text.ParseException;
import java.util.*;

@Component
@EnableScheduling
public class DbConnectCache {

    public static Map<String, JdbcTemplate> jdbcMap= new HashMap<String, JdbcTemplate>();

    public static Map<String, Date> jdbcUseTimeMap= Collections
            .synchronizedMap(new HashMap<String, Date>());

    private static DataSource primaryDataSource(DbConnInfo info) {
        DataSourceBuilder<?> one = DataSourceBuilder.create();
        one.driverClassName(info.getDbType());
        one.password(info.getDbPassword());
        one.url(info.getDbUrl());
        one.username(info.getDbUserName());
        return one.build();
    }

    public static JdbcTemplate getJdbcTemplate(DbConnInfo info){
        if(StringUtil.isNotEmpty(info.getDbType()) && StringUtil.isNotEmpty(info.getDbUserName())
                && StringUtil.isNotEmpty(info.getDbPassword()) && StringUtil.isNotEmpty(info.getDbUrl())){
            if("oracle".equals(info.getDbType())){
                info.setDbType("oracle.jdbc.driver.OracleDriver");
            }else if("SQLServer".equals(info.getDbType())){
                info.setDbType("com.microsoft.sqlserver.jdbc.SQLServerDriver");
            }else{
                return null;
            }
        }
        DataSource dbs = primaryDataSource(info);
        if(dbs != null){
            JdbcTemplate jdbc = new JdbcTemplate (primaryDataSource(info));
            jdbcMap.put(info.getDbConnInfoSn(), jdbc);
            return jdbc;
        }else{
            return null;
        }

    }

    /**
     * 定时检查jdbc对象数
     * @throws ParseException
     */
    @Scheduled(cron = "0/5 * * * * ?")
    private void configureTasks() throws ParseException {
        int count = jdbcMap.size();
        if(count > 5){
            Date now = new Date();
            for(Iterator<String> iterator = jdbcUseTimeMap.keySet().iterator(); iterator.hasNext(); ) {
                String key = iterator.next();
                int hours = DateUtil.compare2DateGetHour(jdbcUseTimeMap.get(key),now);
                if(hours>1){
                    jdbcMap.remove(key);
                    iterator.remove();
                }
            }
        }
        System.gc();
    }
}

获取表名和表结构

/**
 * 获取指定数据库用户下的表名
 * @param info
 * @return
 */
public static List<Map<String, Object>> getTableNameList(DbConnInfo info){
    JdbcTemplate jdbc = null;
    if(DbConnectCache.jdbcMap.containsKey(info.getDbConnInfoSn())){
        jdbc = DbConnectCache.jdbcMap.get(info.getDbConnInfoSn());
    }else{
        jdbc = DbConnectCache.getJdbcTemplate(info);
    }
    if(jdbc != null){
        DbConnectCache.jdbcUseTimeMap.put(info.getDbConnInfoSn(),new Date());
        String sql = "select  TABLE_NAME ,COMMENTS from user_tab_comments where table_type='TABLE'";
        List<Map<String, Object>> list  = jdbc.queryForList(sql);
        return list;
    }else{
        return null;
    }

}


/**
 * 获取指定数据库的指定表的字段和字段注释
 * @param info
 * @param table
 * @return
 */
public static List<Map<String, Object>> getTableField(DbConnInfo info, String table) {
    JdbcTemplate jdbc = null;
    if(DbConnectCache.jdbcMap.containsKey(info.getDbConnInfoSn())){
        jdbc = DbConnectCache.jdbcMap.get(info.getDbConnInfoSn());
    }else{
        jdbc = DbConnectCache.getJdbcTemplate(info);
    }
    if(jdbc != null){
        DbConnectCache.jdbcUseTimeMap.put(info.getDbConnInfoSn(),new Date());
        String sql = "select tmp.*,DATA_TYPE from (select  column_name,comments from user_col_comments where table_name=upper('"+table+"')) tmp"
                +" left join (select  column_name,DATA_TYPE from user_tab_columns " +
                " where table_name = upper('"+table+"'))  tmp0 on tmp.column_name=tmp0.column_name";
         List<Map<String, Object>> list = jdbc.queryForList(sql);
        return list;
    }else{
        return null;
    }
}



4、补充说明

如果数据库在2个且连接信息固定不变,可以考虑用mybatis的databaseId或者数据连接池。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

java通过JdbcTemplate连接多个(2个以上)不同类型的数据库 的相关文章

  • 警告:跳过条目,因为它不是绝对 URI。 NetBeans 中的 GlassFish

    我成功安装了 GlassFish 但是 当我启动服务器时 我收到两条警告消息 警告 跳过条目 因为它不是绝对 URI 那是关于什么的 Launching GlassFish on Felix platform Aug 09 2014 10
  • 我们如何测试我们的 Java UI?

    我们正在寻找记录和回放类型的测试工具来自动化我们的一些 UI 功能测试 我们已经研究了从 Silke 到 QTP 的大多数常见嫌疑 但没有一个起作用 当需要右键单击才能从右键单击菜单中选择某些内容时 或者当您必须在网格的下拉列表中选择一个值
  • JPA:如何将字符串持久保存到数据库字段中,输入 MYSQL Text

    需求是用户可以写文章 所以我选择typeText为了contentmysql数据库内的字段 我怎样才能转换Java String into MySQL Text 干得好Jim Tough Entity public class Articl
  • Ant 无法启动,给出主类错误

    我正在运行 Elementary OS 基于 Ubuntu 12 并且在运行 apache ant 时遇到问题 它在重新启动之前就可以正常工作 所以我不确定会发生什么变化 我在 etc environment 中定义了环境变量 如下所示 P
  • 在 JavaFX 中拖动未装饰的舞台

    我希望将舞台设置为 未装饰 使其可拖动且可最小化 问题是我找不到这样做的方法 因为我遇到的示例是通过插入到主方法中的方法来实现的 我想通过控制器类中声明的方法来完成此操作 就像我如何使用下面的 WindowClose 方法来完成此操作 这是
  • 在java中是否可以使用反射创建没有无参数构造函数的“空白”类实例?

    我有一个没有默认构造函数的类 我需要一种方法来获取此类的 空白 实例 空白 意味着实例化后所有类字段都应具有默认值 如 null 0 等 我问这个问题是因为我需要能够序列化 反序列化大对象树 而且我无法访问该对象类的源 并且类既没有默认构造
  • 我们必须将 .class 文件放在 Tomcat 目录中的位置

    我必须把我的 class文件在 Tomcat 目录中 在我的 Java Complete Reference 书中 他们告诉将其放入C Program Files Apache Tomcat 4 0 webapps examples WEB
  • Java中无参数的for循环

    我在看别人的代码 发现了这段代码 for 我不是 Java 专家 这行代码在做什么 起初 我认为这会创建一个无限循环 但在该程序员使用的同一个类中 while true 其中 如果我错了 请纠正我 是一个无限循环 这两个相同吗 为什么有人会
  • 如何使用 AWS CodeCommit 作为 Spring Cloud Config 的存储库

    我正在尝试将 AWS CodeCommit 存储库与 Spring Cloud 配置结合使用 我已经设法让它与 SSH 一起工作 但我想使用 https 而不是 SSH AWS 建议使用凭证助手 有谁知道如何配置 spring config
  • 使用 Java 通过 HTTP 下载未知长度的文件

    我想用java下载一个HTTP查询 但是我下载的文件在下载时有一个未确定的长度 我认为这将是相当标准的 所以我搜索并找到了它的代码片段 http snipplr com view 33805 http snipplr com view 33
  • 如何告诉 cxf 将包装类型保留在方法中?

    在我的 WSDL 中我有一个操作
  • wsdl 没有服务元素

    我必须使用 WCF Web 服务并获得 WSDL 外部的 因此无法控制 WSDL 在 WSDL 定义中 我没有找到包含服务 端口和地址元素的服务元素 WSDL 中不存在这种情况正常吗 这对于 WCF WSDL 来说很常见吗 我正在尝试使用轴
  • 我可以关闭并重新打开套接字吗?

    我学习了一个使用套接字的例子 在此示例中 客户端向服务器发送请求以打开套接字 然后服务器 侦听特定端口 打开套接字 一切都很好 套接字从双方 客户端和服务器 打开 但我仍然不清楚这个东西有多灵活 例如 客户端是否可以关闭一个打开的 从两端
  • 链表中的虚拟节点

    问 什么时候使用它们 作业问题 列表中的第一个和最后一个节点 有时用作列表中的第一个和最后一个节点 从未用作列表中的第一个和最后一个节点 维基百科说 哨兵节点是与链接一起使用的专门指定的节点 列表和树作为遍历路径终止符 哨兵节点的作用是 不
  • Storm Spout 未收到 Ack

    我已经开始使用storm 所以我使用创建简单的拓扑本教程 https github com nathanmarz storm wiki Tutorial 当我运行我的拓扑时LocalCluster一切看起来都很好 我的问题是我没有得到元组的
  • Apache HttpClient TCP Keep-Alive(套接字保持活动)

    我的 http 请求需要太多时间才能被服务器处理 大约 5 分钟 由于连接闲置 5 分钟 代理服务器将关闭连接 我正在尝试在 Apache DefaultHttpClient 中使用 TCP Keep Alive 来使连接长时间处于活动状态
  • Python 可以替代 Java 小程序吗?

    除了制作用于物理模拟 如抛射运动 重力等 的教育性 Java 小程序之外 还有其他选择吗 如果你想让它在浏览器中运行 你可以使用PyJamas http pyjs org 这是一个 Python 到 Javascript 的编译器和工具集
  • spring data jpa 过滤 @OneToMany 中的子项

    我有一个员工测试实体是父实体并且FunGroup信息子实体 这两个实体都是通过employeeId映射 我需要一种方法来过滤掉与搜索条件匹配的子实体 以便结果仅包含父实体和子实体 满足要求 员工测试类 Entity name Employe
  • 升级到 Tomcat 8 时出现 ClassNotFoundException

    我最近将 NetBeans IDE 从 v7 3 升级到 v8 突然我的应用程序在连接到数据库时在服务器启动时抛出异常 这两个版本的 IDE 之间的唯一区别是后者使用 Tomcat 8 异常日志 javax naming NamingExc
  • 线程“main”中出现异常 java.lang.UnsatisfiedLinkError: ... \jzmq.dll: 找不到依赖库

    我有一个使用 ZMQ 的 java 应用程序 我已经能够在我的 Win7 PC 上运行它 我将 jzmq dll 放在 jar 可执行文件所在的同一文件夹中 然后通过命令 java jar myapp jar 运行它 我的下一步是将其移至服

随机推荐