BaseDaopackage dao;
import java.sql.*;
public class BaseDao {
// ---- MySQL 配置 ----
private static final String DRIVER = "com.mysql.jdbc.Driver";
private static final String URL = "jdbc:mysql://127.0.0.1:3306/school?useUnicode=true&characterEncoding=utf8&useSSL=false";
private static final String USER = "root";
private static final String PASS = "123456";
// Oracle / SQL Server 同理,修改上三常量即可
/** 獲取連線 */
public Connection getConnection() {
Connection conn = null;
try {
Class.forName(DRIVER);
conn = DriverManager.getConnection(URL, USER, PASS);
} catch (Exception e) {
e.printStackTrace();
}
return conn;
}
/** 關閉所有資源(順序:ResultSet → Statement → Connection) */
public void closeAll(Connection conn, PreparedStatement ps, ResultSet rs) {
try {
if (rs != null) rs.close();
if (ps != null) ps.close();
if (conn != null) conn.close();
} catch (Exception e) { e.printStackTrace(); }
}
/** 通用增刪改:支援參數化 SQL */
public int executeUpdate(String sql, String[] params) {
Connection conn = null;
PreparedStatement ps = null;
int result = -1;
try {
conn = getConnection();
ps = conn.prepareStatement(sql);
if (params != null) {
for (int i = 0; i < params.length; i++) {
ps.setString(i + 1, params[i]); // 統一按 String 綁定,簡化類型處理
}
}
result = ps.executeUpdate();
} catch (Exception e) {
System.out.println("SQL 執行異常: " + e.getMessage());
} finally {
closeAll(conn, ps, null);
}
return result;
}
// 查詢方法可自行擴展:executeQuery(sql, params, RowMapper)
public static void main(String[] args) throws Exception {
BaseDao dao = new BaseDao();
Connection c = dao.getConnection();
System.out.println("連線狀態: " + (c != null && !c.isClosed() ? "成功" : "失敗"));
}
}
| 實踐 | 說明 |
|---|---|
使用 PreparedStatement | 預編譯防注入、效能優於 Statement、支援批次處理 |
| 資源關閉順序 | ResultSet → Statement → Connection,反順序可能拋異常導致連線洩漏 |
| 連線池 | 生產環境必須用 HikariCP / Druid,不可每請求新建連線 |
| 異常處理 | 捕獲後記錄日志、拋出業務異常,避免吞噬堆疊資訊 |
| 事務控制 | conn.setAutoCommit(false) + commit/rollback,工具類可加 executeTransaction 方法 |
ResultSet 映射為 POJO,消除重複 getString/getIntLIMIT、Oracle ROWNUM、SQL Server OFFSET FETCH 封裝統一介面NamedParameterJdbcTemplate(Spring)或自行實現 :name 佔位符try (Connection c = pool.getConnection()) { ... } 自動歸還若專案已引入 Spring,建議直接使用 JdbcTemplate / NamedParameterJdbcTemplate,內建連線池整合、異常轉換、資源管理、Lambda 查詢,代碼量減少 70% 以上。