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");
    }
}
相关推荐
IvorySQL7 小时前
PostgreSQL 日报|修复截断 zstd 备份检测(10 月 9 日)
数据库·postgresql
刘胡子大叔7 小时前
SQL 脚本的导入顺序
数据库·sql
代码什么用8 小时前
Spring对IoC的实现
数据库·spring
hz5678910 小时前
涉密视频会议设备配置指南:终端、音视频采集与配套设施选型
服务器·网络·数据库·安全·实时音视频·信息与通信·智能硬件
广州浮点FLOATLIC10 小时前
许可证服务器迁移后软件打不开:研发 IT 怎样定位连接问题
linux·服务器·数据库
程序员Sunday10 小时前
MySQL 为什么使用 B+ 树索引?把范围查询、回表和覆盖索引连起来
数据库·mysql
半杯咖啡半行码10 小时前
Qt开发实战:数据库、MV 模式、QProcess与串口通信全攻略
数据库·qt
小米里的大麦11 小时前
16 MySQL 事务
数据库·mysql
西柚小萌新11 小时前
【LLM&&AI应用开发 八股文】--4.3.Agent智能体(下)
java·开发语言·数据库
邓工说电12 小时前
智慧断路器安全吗?数据加密、离线保护与合规认证全解读
大数据·数据库·人工智能·智能断路器·炜晔科技