项目需要做多个数据库作为数据源,但是由于开发时间有限,并且另外一个数据库基本只需要简单的查询数据,所以选择使用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");
}
}