java
/**
* encoding: utf-8
* 版权所有 2025 ©涂聚文有限公司 ®
* 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
* 描述: https://www.oracle.com/database/technologies/appdev/jdbc-downloads.html ojdbc11
* Author : geovindu,Geovin Du 涂聚文.
* IDE : IntelliJ IDEA 2024.3.6 Java 17
* # database : Oracle21c,MySQL 9.0,SQL Server 2019,PostgreSQL 17.1 Neo4j
* # OS : window10
* Datetime : 2025 - 2025/7/13 - 14:25
* User : geovindu
* Product : IntelliJ IDEA
* Project : oracledemo
* File : DuOracleHelper.java
* explain : 学习 类
**/
package Geovin.UtilitieDB;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.sql.Driver.*;
import java.util.HashMap;
import java.util.Map;
import java.sql.Connection;
import java.sql.DriverManager;
/**
*geovindu,Geovin Du
*/
public class DuOracleHelper {
/**
* 命令类型枚举
*/
public enum CommandType {
TEXT, STORE_PROCEDURE
}
/**
* 参数方向枚举
*/
public enum ParameterDirection {
IN, OUT
}
/**
* 数据库参数类
*/
public static class Parameter {
public String name; // 注意:这个字段在简单查询中可能不需要,但保留用于存储过程
public Object value;
public ParameterDirection direction;
public int type;
/**
* 新增三参数构造函数(用于简单查询)
* @param value
* @param direction
* @param type
*/
public Parameter(Object value, ParameterDirection direction, int type) {
this.name = null; // 简单查询不需要参数名
this.value = value;
this.direction = direction;
this.type = type;
}
/**
* 保留原有的四参数构造函数(用于存储过程)
* @param name
* @param value
* @param direction
* @param type
*/
public Parameter(String name, Object value, ParameterDirection direction, int type) {
this.name = name;
this.value = value;
this.direction = direction;
this.type = type;
}
}
/**
* 数据列类
*/
public static class DataColumn {
public String columnName;
public Object value;
public DataColumn(String columnName, Object value) {
this.columnName = columnName;
this.value = value;
}
@Override
public String toString() {
return "\"" + columnName + "\": " + (value == null ? "null" : "\"" + value.toString() + "\"");
}
}
/**
* 数据行类
*/
public static class DataRow {
private List<DataColumn> columns = new ArrayList<>();
public void addColumn(DataColumn column) {
columns.add(column);
}
public DataColumn getColumn(String columnName) {
for (DataColumn column : columns) {
if (column.columnName.equalsIgnoreCase(columnName)) {
return column;
}
}
return null;
}
public List<DataColumn> getColumns() {
return columns;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder("{");
for (int i = 0; i < columns.size(); i++) {
sb.append(columns.get(i).toString());
if (i < columns.size() - 1) {
sb.append(", ");
}
}
sb.append("}");
return sb.toString();
}
}
/**
* 数据表类
*/
public static class DataTable {
private List<DataRow> rows = new ArrayList<>();
public void addRow(DataRow row) {
rows.add(row);
}
public List<DataRow> getRows() {
return rows;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder("[");
for (int i = 0; i < rows.size(); i++) {
sb.append(rows.get(i).toString());
if (i < rows.size() - 1) {
sb.append(",\n");
}
}
sb.append("]");
return sb.toString();
}
}
/**
* 数据集类
*/
public static class DataSet {
private List<DataTable> tables = new ArrayList<>();
public void addTable(DataTable table) {
tables.add(table);
}
public List<DataTable> getTables() {
return tables;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder("{");
for (int i = 0; i < tables.size(); i++) {
sb.append("\"table").append(i).append("\": ").append(tables.get(i).toString());
if (i < tables.size() - 1) {
sb.append(",\n");
}
}
sb.append("}");
return sb.toString();
}
}
/**
* 从JSON配置文件读取数据库连接信息
* @param configFilePath 配置文件路径
* @return 包含数据库连接信息的Map
* @throws IOException 如果读取文件或解析JSON出错
*/
public static Map<String, String> getConnectionInfo(String configFilePath) throws IOException {
StringBuilder content = new StringBuilder();
try (BufferedReader reader = new BufferedReader(new FileReader(configFilePath))) {
String line;
while ((line = reader.readLine()) != null) {
content.append(line);
}
}
// 解析JSON配置
Map<String, String> config = new HashMap<>();
// 简单解析,忽略JSON格式的复杂性
String[] pairs = content.toString().replaceAll("[{}\"]", "").split(",");
for (String pair : pairs) {
String[] keyValue = pair.split(":");
if (keyValue.length == 2) {
config.put(keyValue[0].trim(), keyValue[1].trim());
}
}
// 验证必要的配置项
if (!config.containsKey("host") ||
!config.containsKey("port") ||
!config.containsKey("serviceName") ||
!config.containsKey("user") ||
!config.containsKey("password")) {
throw new IOException("配置文件缺少必要的连接参数");
}
return config;
}
/**
* 创建Oracle数据库连接
* @param configFilePath 配置文件路径
* @return Connection对象
* @throws SQLException 如果连接数据库失败
* @throws IOException 如果读取配置文件失败
*/
public static Connection getConnection(String configFilePath) throws SQLException, IOException {
Map<String, String> config = getConnectionInfo(configFilePath);
try {
// 加载Oracle驱动
Class.forName("oracle.jdbc.OracleDriver");
} catch (ClassNotFoundException e) {
throw new SQLException("找不到Oracle JDBC驱动", e);
}
// 构建Oracle连接字符串
String host = config.get("host");
String port = config.get("port");
String serviceName = config.get("serviceName");
String user = config.get("user");
String password = config.get("password");
if (host == null || port == null || serviceName == null || user == null || password == null) {
throw new IOException("配置文件缺少必要的连接参数");
}
// 构建连接URL jdbc:oracle:thin:@//localhost:1521/TechnologyGame
String url = String.format("jdbc:oracle:thin:@//%s:%s/%s",
config.get("host"),
config.get("port"),
config.get("serviceName"));
// 创建连接
return DriverManager.getConnection(url, config.get("user"), config.get("password"));
}
/**
* 执行查询并返回DataSet
* @param configFilePath
* @param commandType
* @param commandText
* @return
* @throws Exception
*/
public static DataSet executeDataSet(String configFilePath, CommandType commandType, String commandText) throws Exception {
return executeDataSet(configFilePath, commandType, commandText, new Parameter[0]);
}
/**
* 执行查询并返回DataSet,带参数
* @param configFilePath
* @param commandType
* @param commandText
* @param parameters
* @return
* @throws Exception
*/
public static DataSet executeDataSet(String configFilePath, CommandType commandType, String commandText, Parameter... parameters) throws Exception {
try (Connection conn = getConnection(configFilePath)) {
return executeDataSet(conn, commandType, commandText, parameters);
}
}
/**
* 执行查询并返回DataSet
* @param connection
* @param commandType
* @param commandText
* @return
* @throws Exception
*/
public static DataSet executeDataSet(Connection connection, CommandType commandType, String commandText) throws Exception {
return executeDataSet(connection, commandType, commandText, new Parameter[0]);
}
/**
* * 执行查询并返回DataSet,带参数
* @param connection
* @param commandType
* @param commandText
* @param parameters
* @return
* @throws Exception
*/
public static DataSet executeDataSet(Connection connection, CommandType commandType, String commandText, Parameter... parameters) throws Exception {
DataSet ds = new DataSet();
System.out.println("开始执行查询: " + commandText);
if (commandType == CommandType.TEXT) {
try (PreparedStatement pstmt = connection.prepareStatement(commandText)) {
// 设置参数
for (int i = 0; i < parameters.length; i++) {
Parameter p = parameters[i];
if (p.direction == ParameterDirection.IN) {
System.out.println("设置输入参数 " + (i + 1) + ": " + p.name + " = " + p.value);
pstmt.setObject(i + 1, p.value, p.type);
}
}
// 执行查询
try (ResultSet rs = pstmt.executeQuery()) {
System.out.println("执行SQL查询成功,开始处理结果集");
DataTable dt = convertResultSetToDataTable(rs);
System.out.println("结果集转换为DataTable,包含 " + dt.getRows().size() + " 行");
ds.addTable(dt);
}
}
} else if (commandType == CommandType.STORE_PROCEDURE) {
StringBuilder paramPlaceholders = new StringBuilder();
for (int i = 0; i < parameters.length; i++) {
paramPlaceholders.append("?, ");
}
if (paramPlaceholders.length() > 0) {
paramPlaceholders = new StringBuilder(" ( " + paramPlaceholders.substring(0, paramPlaceholders.length() - 2) + " ) ");
}
String sql = "{ call " + commandText + paramPlaceholders + " }";
System.out.println("准备调用存储过程: " + sql);
try (CallableStatement proc = connection.prepareCall(sql)) {
// 设置参数
for (int i = 0; i < parameters.length; i++) {
Parameter p = parameters[i];
System.out.println("设置参数 " + (i + 1) + ": " + p.name + " (方向: " + p.direction + ", 类型: " + p.type + ")");
if (p.direction == ParameterDirection.IN) {
proc.setObject(i + 1, p.value, p.type);
} else if (p.direction == ParameterDirection.OUT) {
proc.registerOutParameter(i + 1, p.type);
}
}
// 执行存储过程
System.out.println("开始执行存储过程...");
boolean hasResultSet = proc.execute();
System.out.println("存储过程执行完成,是否有结果集: " + hasResultSet);
// 处理所有结果集
int resultSetCount = 0;
while (hasResultSet) {
try (ResultSet rs = proc.getResultSet()) {
System.out.println("处理结果集 #" + (resultSetCount + 1));
if (rs != null) {
DataTable dt = convertResultSetToDataTable(rs);
System.out.println("结果集 #" + (resultSetCount + 1) + " 包含 " + dt.getRows().size() + " 行");
ds.addTable(dt);
resultSetCount++;
} else {
System.out.println("结果集 #" + (resultSetCount + 1) + " 为空");
}
}
hasResultSet = proc.getMoreResults();
System.out.println("是否还有更多结果集: " + hasResultSet);
}
// 处理输出参数
System.out.println("开始处理输出参数...");
for (int i = 0; i < parameters.length; i++) {
Parameter p = parameters[i];
if (p.direction == ParameterDirection.OUT) {
p.value = proc.getObject(i + 1);
System.out.println("输出参数 " + (i + 1) + " (" + p.name + ") 的值: " + p.value);
// 特殊处理 Oracle 游标
if (p.type == oracle.jdbc.OracleTypes.CURSOR) {
System.out.println("检测到游标参数,尝试获取结果集...");
// 使用 Oracle 特定的 API 获取游标
oracle.jdbc.OracleCallableStatement oracleProc = (oracle.jdbc.OracleCallableStatement) proc;
ResultSet rs = oracleProc.getCursor(i + 1);
if (rs != null) {
System.out.println("成功获取游标结果集,开始转换...");
DataTable dt = convertResultSetToDataTable(rs);
System.out.println("游标结果集包含 " + dt.getRows().size() + " 行");
ds.addTable(dt);
// 关闭结果集
rs.close();
} else {
System.out.println("游标结果集为空");
}
}
}
}
System.out.println("处理了 " + resultSetCount + " 个结果集和 " + parameters.length + " 个输出参数");
}
} else {
throw new IllegalArgumentException("不支持的命令类型: " + commandType);
}
System.out.println("DataSet 包含 " + ds.getTables().size() + " 个表,总共 " +
ds.getTables().stream().mapToInt(t -> t.getRows().size()).sum() + " 行数据");
// 打印详细数据结构(调试用)
if (ds.getTables().size() > 0) {
System.out.println("第一个表的结构: " + ds.getTables().get(0));
}
return ds;
}
/**
* 执行非查询命令
* @param configFilePath
* @param commandType
* @param commandText
* @throws Exception
*/
public static void executeNonQuery(String configFilePath, CommandType commandType, String commandText) throws Exception {
executeNonQuery(configFilePath, commandType, commandText, new Parameter[0]);
}
/**
* 执行非查询命令,带参数
* @param configFilePath
* @param commandType
* @param commandText
* @param parameters
* @throws Exception
*/
public static void executeNonQuery(String configFilePath, CommandType commandType, String commandText, Parameter... parameters) throws Exception {
try (Connection conn = getConnection(configFilePath)) {
executeNonQuery(conn, commandType, commandText, parameters);
}
}
/**
* 执行非查询命令
* @param connection
* @param commandType
* @param commandText
* @throws Exception
*/
public static void executeNonQuery(Connection connection, CommandType commandType, String commandText) throws Exception {
executeNonQuery(connection, commandType, commandText, new Parameter[0]);
}
/**
* 执行非查询命令,带参数
* @param connection
* @param commandType
* @param commandText
* @param parameters
* @throws Exception
*/
public static void executeNonQuery(Connection connection, CommandType commandType, String commandText, Parameter... parameters) throws Exception {
if (commandType == CommandType.TEXT) {
try (PreparedStatement pstmt = connection.prepareStatement(commandText)) {
// 设置参数
for (int i = 0; i < parameters.length; i++) {
Parameter p = parameters[i];
if (p.direction == ParameterDirection.IN) {
pstmt.setObject(i + 1, p.value, p.type);
}
}
// 执行更新
pstmt.executeUpdate();
}
} else if (commandType == CommandType.STORE_PROCEDURE) {
StringBuilder paramPlaceholders = new StringBuilder();
for (int i = 0; i < parameters.length; i++) {
paramPlaceholders.append("?, ");
}
if (paramPlaceholders.length() > 0) {
paramPlaceholders = new StringBuilder(" ( " + paramPlaceholders.substring(0, paramPlaceholders.length() - 2) + " ) ");
}
String sql = "{ call " + commandText + paramPlaceholders + " }";
try (CallableStatement proc = connection.prepareCall(sql)) {
// 设置参数
for (int i = 0; i < parameters.length; i++) {
Parameter p = parameters[i];
if (p.direction == ParameterDirection.IN) {
proc.setObject(i + 1, p.value, p.type);
} else if (p.direction == ParameterDirection.OUT) {
proc.registerOutParameter(i + 1, p.type);
}
}
// 执行存储过程
proc.execute();
// 处理输出参数
for (int i = 0; i < parameters.length; i++) {
Parameter p = parameters[i];
if (p.direction == ParameterDirection.OUT) {
p.value = proc.getObject(i + 1);
}
}
}
} else {
throw new IllegalArgumentException("不支持的命令类型: " + commandType);
}
}
/**
* 将ResultSet转换为DataTable
* @param rs
* @return
* @throws Exception
*/
private static DataTable convertResultSetToDataTable(ResultSet rs) throws Exception {
ResultSetMetaData rsmd = rs.getMetaData();
int columnCount = rsmd.getColumnCount();
DataTable dt = new DataTable();
while (rs.next()) {
DataRow dr = new DataRow();
for (int i = 1; i <= columnCount; i++) {
DataColumn dc = new DataColumn(rsmd.getColumnName(i), rs.getObject(i));
dr.addColumn(dc);
}
dt.addRow(dr);
}
return dt;
}
}
java
/**
*
* @param schoolId
* @return DataSet
*/
@Override
public DuOracleHelper.DataSet getSchoolByDataSet(String schoolId) {
String sql = "SELECT * FROM School WHERE SchoolId = ?";
try {
// 示例1:执行SQL查询
DuOracleHelper.DataSet resultSet = DuOracleHelper.executeDataSet(
"oraclecon.json",
DuOracleHelper.CommandType.TEXT,
sql,
new DuOracleHelper.Parameter(schoolId, DuOracleHelper.ParameterDirection.IN, Types.VARCHAR)
);
return resultSet;
}
catch (Exception e) {
e.printStackTrace();
return null;
}
}
调用:
java
DuOracleHelper.DataSet resultSet =schoolBLL.getSchoolByDataSet("U0040");
System.out.println(resultSet.toString());
项目结构:
