JDBC直连ORACLE进行查询

项目需要做多个数据库作为数据源,但是由于开发时间有限,并且另外一个数据库基本只需要简单的查询数据,所以选择使用jdbc来查询第二个数据库。

实战

配置

yml 复制代码
# src/main/resources/application.yml
# 主数据源配置(Spring Boot 自动管理部分)
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/your_primary_db
    username: your_mysql_username
    password: your_mysql_password

# 自定义的第二个 Oracle 数据库配置(您要直连的数据库)
app:
  datasource:
    oracle:
      jdbc-url: jdbc:oracle:thin:@//oracle-host:1521/your_service_name
      username: your_oracle_username
      password: your_oracle_password
      driver-class-name: oracle.jdbc.OracleDriver
      # HikariCP 连接池配置
      maximum-pool-size: 10
      minimum-idle: 5
      connection-timeout: 30000
      idle-timeout: 600000
      max-lifetime: 1800000

配置类

复制代码
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;

/**
 * 基于 YAML 配置的 JDBC 工具类
 * 使用 HikariCP 连接池管理数据库连接
 */
@Component
public class JdbcUtilsYaml {

    // 从 YAML 配置文件中注入属性[7,8](@ref)
    private static String url;
    private static String username;
    private static String password;
    private static String driverClassName;
    private static int maxPoolSize;
    private static int minIdle;
    
    private static HikariDataSource dataSource;

    @Value("${app.datasource.oracle.jdbc-url}")
    public void setUrl(String url) {
        JdbcUtilsYaml.url = url;
    }

    @Value("${app.datasource.oracle.username}")
    public void setUsername(String username) {
        JdbcUtilsYaml.username = username;
    }

    @Value("${app.datasource.oracle.password}")
    public void setPassword(String password) {
        JdbcUtilsYaml.password = password;
    }

    @Value("${app.datasource.oracle.driver-class-name}")
    public void setDriverClassName(String driverClassName) {
        JdbcUtilsYaml.driverClassName = driverClassName;
    }

    @Value("${app.datasource.oracle.maximum-pool-size:10}")
    public void setMaxPoolSize(int maxPoolSize) {
        JdbcUtilsYaml.maxPoolSize = maxPoolSize;
    }

    @Value("${app.datasource.oracle.minimum-idle:5}")
    public void setMinIdle(int minIdle) {
        JdbcUtilsYaml.minIdle = minIdle;
    }

    /**
     * 初始化连接池[6](@ref)
     */
    @PostConstruct
    public void init() {
        try {
            HikariConfig config = new HikariConfig();
            config.setJdbcUrl(url);
            config.setUsername(username);
            config.setPassword(password);
            config.setDriverClassName(driverClassName);
            config.setMaximumPoolSize(maxPoolSize);
            config.setMinimumIdle(minIdle);
            config.setConnectionTimeout(30000);
            config.setIdleTimeout(600000);
            config.setMaxLifetime(1800000);
            
            dataSource = new HikariDataSource(config);
            System.out.println("Oracle 数据库连接池初始化成功!");
        } catch (Exception e) {
            throw new RuntimeException("初始化数据库连接池失败", e);
        }
    }

    /**
     * 获取数据库连接[3](@ref)
     */
    public static Connection getConnection() throws SQLException {
        if (dataSource == null) {
            throw new SQLException("数据源未正确初始化");
        }
        return dataSource.getConnection();
    }

    /**
     * 关闭数据源(在应用关闭时调用)
     */
    public static void closeDataSource() {
        if (dataSource != null && !dataSource.isClosed()) {
            dataSource.close();
            System.out.println("数据库连接池已关闭");
        }
    }
}

使用示例

复制代码
import org.springframework.stereotype.Service;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

@Service
public class YourService {

    public void queryFromOracle() {
        // 使用 try-with-resources 自动管理资源[1](@ref)
        String sql = "SELECT * FROM your_table WHERE id = ?";
        
        try (Connection conn = JdbcUtilsYaml.getConnection();
             PreparedStatement pstmt = conn.prepareStatement(sql)) {
            
            pstmt.setInt(1, 123);
            
            try (ResultSet rs = pstmt.executeQuery()) {
                while (rs.next()) {
                    String data = rs.getString("column_name");
                    System.out.println("查询结果: " + data);
                }
            }
        } catch (SQLException e) {
            System.err.println("数据库操作失败: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

查询结果转List<实体>

复制代码
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * ResultSet 转换工具类 (基于 Gson)
 * 功能:ResultSet 转 JSON字符串,JSON字符串 转 List<实体类>
 */
public class ResultSetJsonUtil {
    
    private static final Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();

    /**
     * 将 ResultSet 转换为 JSON 字符串
     * @param rs 数据库结果集
     * @return JSON 格式的字符串
     * @throws SQLException
     */
    public static String resultSetToJson(ResultSet rs) throws SQLException {
        List<Map<String, Object>> resultList = new ArrayList<>();
        ResultSetMetaData metaData = rs.getMetaData();
        int columnCount = metaData.getColumnCount();

        // 遍历 ResultSet
        while (rs.next()) {
            Map<String, Object> rowMap = new HashMap<>();
            for (int i = 1; i <= columnCount; i++) {
                String columnName = metaData.getColumnLabel(i); // 或 getColumnName
                Object value = rs.getObject(i);
                
                // 处理特定类型(如 Timestamp)
                if (value instanceof Timestamp) {
                    value = rs.getTimestamp(i); // 保留为 Timestamp,由 Gson 的日期格式处理
                }
                rowMap.put(columnName, value);
            }
            resultList.add(rowMap);
        }
        return gson.toJson(resultList);
    }

    /**
     * 将 JSON 字符串转换为 List<实体类>
     * @param jsonStr JSON 字符串
     * @param clazz 目标实体类的 Class 对象
     * @return 实体对象列表
     */
    public static <T> List<T> jsonToList(String jsonStr, Class<T> clazz) {
        Type listType = TypeToken.getParameterized(List.class, clazz).getType();
        return gson.fromJson(jsonStr, listType);
    }

    /**
     * 将 ResultSet 直接转换为 List<实体类> (便捷方法)
     * @param rs 数据库结果集
     * @param clazz 目标实体类的 Class 对象
     * @return 实体对象列表
     */
    public static <T> List<T> resultSetToList(ResultSet rs, Class<T> clazz) throws SQLException {
        String jsonStr = resultSetToJson(rs);
        return jsonToList(jsonStr, clazz);
    }
}

调用示例

复制代码
import java.sql.*;
import java.util.List;

public class UserService {
    
    public void demoQuery() {
        String sql = "SELECT id, name, email, age, create_time FROM users WHERE age > ?";
        
        // 使用 try-with-resources 自动管理资源
        try (Connection conn = getConnection(); // 您的数据库连接
             PreparedStatement pstmt = conn.prepareStatement(sql)) {
            
            pstmt.setInt(1, 18); // 设置参数
            
            try (ResultSet rs = pstmt.executeQuery()) {
                
                // 方法1: 先转JSON字符串,再转List(可分步调试)
                String jsonResult = ResultSetJsonUtil.resultSetToJson(rs);
                System.out.println("JSON结果: " + jsonResult);
                
                // 将JSON转换为List<User>
                List<User> userList = ResultSetJsonUtil.jsonToList(jsonResult, User.class);
                
                // 方法2: 或者直接一步到位(推荐)
                // List<User> userList = ResultSetJsonUtil.resultSetToList(rs, User.class);
                
                // 使用结果
                for (User user : userList) {
                    System.out.println("用户: " + user.getName() + ", 邮箱: " + user.getEmail());
                }
                
                System.out.println("共查询到 " + userList.size() + " 条记录");
            }
            
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
    
    // 获取数据库连接的方法(需根据您的配置实现)
    private Connection getConnection() throws SQLException {
        // 返回您的数据库连接
        return DriverManager.getConnection("jdbc:mysql://localhost:3306/your_db", "user", "password");
    }
}
相关推荐
李广坤16 小时前
MySQL 大表字段变更实践(改名 + 改类型 + 改长度)
数据库
爱可生开源社区2 天前
2026 年,优秀的 DBA 需要具备哪些素质?
数据库·人工智能·dba
随逸1772 天前
《从零搭建NestJS项目》
数据库·typescript
加号33 天前
windows系统下mysql多源数据库同步部署
数据库·windows·mysql
シ風箏3 天前
MySQL【部署 04】Docker部署 MySQL8.0.32 版本(网盘镜像及启动命令分享)
数据库·mysql·docker
李慕婉学姐3 天前
Springboot智慧社区系统设计与开发6n99s526(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
数据库·spring boot·后端
百锦再3 天前
Django实现接口token检测的实现方案
数据库·python·django·sqlite·flask·fastapi·pip
tryCbest3 天前
数据库SQL学习
数据库·sql
jnrjian3 天前
ORA-01017 查找机器名 用户名 以及library cache lock 参数含义
数据库·oracle
十月南城3 天前
数据湖技术对比——Iceberg、Hudi、Delta的表格格式与维护策略
大数据·数据库·数据仓库·hive·hadoop·spark