Java: OracleHelper

/*** 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;}@Overridepublic 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;}@Overridepublic 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;}@Overridepublic 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;}@Overridepublic 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/TechnologyGameString 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;}
}
/**** @param schoolId* @return DataSet*/@Overridepublic 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;}}

調用:

 DuOracleHelper.DataSet resultSet =schoolBLL.getSchoolByDataSet("U0040");System.out.println(resultSet.toString());

項目結構:

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/89087.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/89087.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/89087.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

OSPFv3-一二類LSA

文章目錄OSPFv3 LSA類型Router LSANetwork LSA&#x1f3e1;作者主頁&#xff1a;點擊&#xff01; &#x1f916;Datacom專欄&#xff1a;點擊&#xff01; ??創作時間&#xff1a;2025年07月12日20點01分 OSPFv3 LSA類型 Router LSA 不再包含地址信息&#xff0c;使能 OS…

HugeGraph 【圖數據庫】JAVA調用SDK

1.引入依賴<dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>28.0-jre</version> </dependency><dependency><groupId>com.squareup.okhttp3</groupId><artifac…

軟考中級【網絡工程師】第6版教材 第2章 數據通信基礎(中)

考點分析&#xff1a;重要程度&#xff1a;???&#xff0c;本章可能是全書最難的章節&#xff0c;偏理論&#xff0c;公式多除了傳輸介質&#xff0c;其他知識點只考選擇題&#xff0c;考試一般占3 ~ 5分高頻考點&#xff1a;PCM、奈奎斯特定理、曼徹斯特編碼&#xff1b;難…

單片機(STM32-中斷)

一、中斷基礎知識 1.概念 中斷&#xff08;Interrupt&#xff09;是一種特殊的事件處理機制。當CPU正在執行主程序時&#xff0c;如果出現了某些緊急或重要的事件&#xff08;如外設請求、定時器溢出等&#xff09;&#xff0c;可以暫時中止當前的程序&#xff0c;轉而去處理…

gitlab-ci.yml

.gitlab-ci.yml 文件的位置 該文件應放置在 GitLab 項目的代碼倉庫的根目錄 下&#xff0c;具體說明如下&#xff1a;存儲庫根目錄 .gitlab-ci.yml 是 GitLab 持續集成&#xff08;CI&#xff09;的配置文件&#xff0c;需直接放在項目的代碼倉庫的根目錄&#xff08;與 .git 目…

使用JS編寫一個購物車界面

使用JS編寫一個購物車界面 今天我們來剖析一個精心設計的家具商店購物車頁面&#xff0c;這個頁面不僅美觀大方&#xff0c;還具備豐富的交互功能。讓我們一步步拆解它的設計理念和技術實現&#xff01; 頁面展示 頁面整體結構 這個購物車頁面采用了經典的電商布局模式&…

零信任安全架構:如何在云環境中重構網絡邊界?

一、云原生時代&#xff1a;傳統防火墻為何轟然倒塌&#xff1f; 當業務碎片化散落在AWS、阿里云、私有IDC&#xff0c;當員工隨手在咖啡廳WiFi連接生產數據庫&#xff0c;“內網可信”的基石瞬間崩塌&#xff0c;傳統防火墻徹底淪為馬奇諾防線&#xff1a; 邊界消亡&#xff1…

css實現燒香效果

效果&#xff1a;代碼&#xff1a;<!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>動態香燭效果&…

硬件產品的技術資料管控是確保研發可追溯、生產可復制、質量可控制的核心環節。

硬件產品的技術資料管控是確保研發可追溯、生產可復制、質量可控制的核心環節。以下針對BOM單、PCB文件、程序代碼、原理圖四大核心要素&#xff0c;結合行業實踐提出管控方向劃分及優化策略&#xff1a;&#x1f4cb; 一、硬件BOM單的精細化管控方向BOM單是硬件生產的“配方表…

Uniswap V2/V3/V4簡短說明

Uniswap 是以太坊上最知名的去中心化交易所&#xff08;DEX&#xff09;&#xff0c;它通過不同的版本&#xff08;V2、V3、V4&#xff09;不斷改進&#xff0c;變得更高效、更靈活。以下是用通俗易懂的方式介紹它們之間的異同&#xff1a; Uniswap V2&#xff1a;基礎版&#…

C++面向對象創建打印算術表達式樹

C面向對象&#xff0c;實現算術表達式樹的創建和打印的案例&#xff0c;來源于《C沉思錄》第八章&#xff0c;涉及數據抽象、繼承、多態&#xff08;動態綁定&#xff09;、句柄&#xff0c;其中句柄的使用是核心&#xff0c;關于句柄的較為簡單的文章鏈接點擊這里&#xff0c;…

力扣每日一題--2025.7.16

&#x1f4da; 力扣每日一題–2025.7.16 &#x1f4da; 3201. 找出有效子序列的最大長度 I&#xff08;中等&#xff09; 今天我們要解決的是力扣上的第 3201 題——找出有效子序列的最大長度 I。這道題雖然標記為中等難度&#xff0c;但只要掌握了正確的思路&#xff0c;就能…

SFT:大型語言模型專業化定制的核心技術體系——原理、創新與應用全景

本文由「大千AI助手」原創發布&#xff0c;專注用真話講AI&#xff0c;回歸技術本質。拒絕神話或妖魔化。搜索「大千AI助手」關注我&#xff0c;一起撕掉過度包裝&#xff0c;學習真實的AI技術&#xff01; 以下基于權威期刊、會議論文及技術報告&#xff0c;對監督微調&#x…

若依前后端分離框架配置多數據庫表

若依前后端分離框架配置多數據庫表1、配置application.yml2、注釋掉application-druid.yml中的數據庫3、在DataSourceType 中添加新增的數據庫來源4、配置DruidConfig文件4、1新增注入方法&#xff0c;在DataSourceType類添加數據源枚舉4、2在DruidConfig類dataSource方法添加數…

29.安卓逆向2-frida hook技術-逆向os文件(二)IDA工具下載和使用(利用ai分析so代碼)

免責聲明&#xff1a;內容僅供學習參考&#xff0c;請合法利用知識&#xff0c;禁止進行違法犯罪活動&#xff01; 內容參考于&#xff1a;圖靈Python學院 工具下載&#xff1a; 鏈接&#xff1a;https://pan.baidu.com/s/1bb8NhJc9eTuLzQr39lF55Q?pwdzy89 提取碼&#xff1…

[析]Deep reinforcement learning for drone navigation using sensor data

Deep reinforcement learning for drone navigation using sensor data 基于傳感器數據的無人機導航深度強化學習方法 評價&#xff1a;MDP無記憶性&#xff0c;使用LSTM補足缺點。PPO解決新舊策略差距大的問題。 對于環境中的障礙物&#xff0c;設置增量課程&#xff0c;障礙…

SpringBoot項目啟動報:java: 找不到符號 符號: 變量 log 的解決辦法

問題&#xff1a;使用IDEA創建SpringBoot項目&#xff0c;在項目中使用 Slf4j 注解引入log日志后&#xff0c;啟動項目&#xff0c;報如下錯誤&#xff1a;原因&#xff1a;網上找了很多博文&#xff0c;說是lombook依賴沒有引入&#xff0c;但是我的pom.xml中已經引入 lombook…

HTML基礎知識 二(創建容器和表格)

HTML 基礎知識&#xff1a;創建容器和表格&#xff08;補充版&#xff09;HTML&#xff08;超文本標記語言&#xff09;是構建網頁的基礎。容器元素用于組織內容&#xff0c;表格用于展示結構化數據&#xff0c;兩者都是網頁設計中不可或缺的部分。一、HTML 容器元素容器元素就…

多目標優化|HKELM混合核極限學習機+NSGAII算法工藝參數優化、工程設計優化,四目標(最大化輸出y1、最小化輸出y2,y3,y4),Matlab完整源碼

基本介紹 1.HKELM混合核極限學習機NSGAII多目標優化算法&#xff0c;工藝參數優化、工程設計優化&#xff01;&#xff08;Matlab完整源碼和數據&#xff09; 多目標優化是指在優化問題中同時考慮多個目標的優化過程。在多目標優化中&#xff0c;通常存在多個沖突的目標&#x…

【AI智能體】Dify 基于知識庫搭建智能客服問答應用詳解

目錄 一、前言 二、Dify 介紹 2.1 Dify 核心特點 三、AI智能體構建智能客服系統介紹 3.1 基于AI智能體平臺搭建智能客服系統流程 3.1.1 需求分析與場景設計 3.1.2 選擇合適的AI智能體平臺 3.1.3 工作流編排與調試 3.1.4 系統集成與發布 3.2 使用AI智能體構建智能客服系…