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");
    }
}
相关推荐
萧曵 丶20 小时前
Next-Key Lock、记录锁、间隙锁浅谈
数据库·sql·mysql·mvcc·可重复读·幻读
做cv的小昊20 小时前
【TJU】信息检索与分析课程笔记和练习(7)数据库检索—Ei
数据库·笔记·学习·全文检索
zgl_2005377921 小时前
ZGLanguage 解析SQL数据血缘 之 标识提取SQL语句中的目标表
java·大数据·数据库·数据仓库·hadoop·sql·源代码管理
莳花微语21 小时前
记录一次OGG进程abended,报错OGG-01431、OGG-01003、OGG-01151、OGG-01296问题的处理
数据库·sql·mysql
尋有緣21 小时前
力扣1355-活动参与者
大数据·数据库·leetcode·oracle·数据库开发
萧曵 丶21 小时前
MySQL三大日志系统浅谈
数据库·sql·mysql
煎蛋学姐21 小时前
SSM校园兼职招聘系统x6u36(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面
数据库·企业管理·ssm 框架·校园兼职招聘系统
ChineHe1 天前
Redis基础篇004_Redis Pipeline流水线详解
数据库·redis·缓存
西柚补习生1 天前
通用 PWM 原理基础教学
数据库·mongodb