首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

JDBC 連接 MySQL 經典工具類:連接池、PreparedStatement、結果集封裝最佳實踐

     編輯:MySQL 綜合教學

JDBC 連接 MySQL 經典工具類:DatabaseUtil 完整實現與最佳實踐解析

本文提供一個生產級可用的 DatabaseUtil 類,封裝了連接獲取、查詢、更新、資源關閉全流程,採用 PreparedStatement 防注入、try-with-resources 思想手動管理資源,適合中小項目直接引入或作為教學參考。

完整源碼

package com.excelExport.util;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class DatabaseUtil {
    // === 配置常量(建議外置到 properties/yaml)===
    private static final String DRIVER = "com.mysql.jdbc.Driver";
    private static final String URL    = "jdbc:mysql://localhost:3306/tmdest";
    private static final String USER   = "root";
    private static final String PWD    = "123456";

    // === 線程不安全的實例字段(僅供單線程演示,生產請用連接池)===
    private Connection con = null;
    private PreparedStatement ps = null;
    public ResultSet rs = null;  // 暴露給調用者遍歷,調用者負責關閉

    /** 獲取數據庫連接 */
    public void getConnection() {
        try {
            Class.forName(DRIVER);
            con = DriverManager.getConnection(URL, USER, PWD);
        } catch (ClassNotFoundException | SQLException e) {
            e.printStackTrace();
        }
    }

    /** 查詢操作,返回 ResultSet(調用者必須遍歷後調用 closeAll()) */
    public ResultSet getQuery(String sql, String[] params) {
        getConnection();
        try {
            ps = con.prepareStatement(sql);
            if (params != null) {
                for (int i = 0; i < params.length; i++) {
                    ps.setString(i + 1, params[i]);
                }
            }
            rs = ps.executeQuery();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return rs;  // 注意:此處不關閉資源,交由調用者遍歷完後調用 closeAll()
    }

    /** 更新操作(INSERT/UPDATE/DELETE),返回影響行數 */
    public int getUpdate(String sql, String[] params) {
        int row = 0;
        getConnection();
        try {
            ps = con.prepareStatement(sql);
            if (params != null) {
                for (int i = 0; i < params.length; i++) {
                    ps.setString(i + 1, params[i]);
                }
            }
            row = ps.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            closeAll();  // 更新類操作可立即釋放
        }
        return row;
    }

    /** 關閉所有資源 */
    private void closeAll() {
        try {
            if (rs != null) rs.close();
            if (ps != null) ps.close();
            if (con != null) con.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

關鍵設計點解析

維度當前實現生產級建議
連接管理每次操作新建連接引入 HikariCP/Druid 連接池,複用連接,配置最大/最小閒置、超時、驗證查詢
線程安全實例字段共享,非線程安全方法內局部變量持有連接/語句/結果集,或使用 ThreadLocal 綁定事務
資源關閉手動 closeAll(),易忘調用Java 7+ try-with-resources 自動關閉;或封裝 execute(queryConsumer) 模板方法
參數綁定僅支持 String 類型重載 setObject(int, Object) 支持 Date/Integer/BigDecimal 等
異常處理打印堆疊返回 null/0拋出自定義異常(DataAccessException),上層統一處理、記錄、告警
配置外置硬編碼常量Spring @Value / @ConfigurationProperties 注入,區分 dev/test/prod 環境

改進版模板方法模式(推薦)

public  T executeQuery(String sql, Object[] params, ResultSetHandler handler) {
    try (Connection con = dataSource.getConnection();
         PreparedStatement ps = con.prepareStatement(sql)) {
        setParams(ps, params);
        try (ResultSet rs = ps.executeQuery()) {
            return handler.handle(rs);
        }
    } catch (SQLException e) {
        throw new DataAccessException("Query failed: " + sql, e);
    }
}

@FunctionalInterface
public interface ResultSetHandler {
    T handle(ResultSet rs) throws SQLException;
}

使用示例

DatabaseUtil util = new DatabaseUtil();
// 查詢
ResultSet rs = util.getQuery("SELECT * FROM user WHERE name = ?", new String[]{"Tom"});
while (rs.next()) {
    System.out.println(rs.getString("email"));
}
util.closeAll();  // 必須調用

// 更新
int affected = util.getUpdate("UPDATE user SET age = ? WHERE name = ?", new String[]{"25", "Tom"});
System.out.println("影響行數: " + affected);

此工具類展示了 JDBC 核心 API 的標準用法,理解其原理後,強烈建議直接使用成熟框架或連接池,專注業務邏輯而非基礎設施重複造輪子。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved