本文提供一個封裝良好的 MySQLCon JavaBean 組件,實現 MySQL 連接管理、查詢執行、更新操作與資源釋放,並分析其設計優缺點與現代改進方向。
package com.example.db;
import java.sql.*;
public class MySQLCon {
private String dbName = "";
private String password = "";
private String url = "";
private Connection conn = null;
private Statement stmt = null;
private ResultSet rs = null;
public void setDbName(String name) { this.dbName = name; }
public void setPassword(String pass) { this.password = pass; }
public void buildConnection() throws SQLException, ClassNotFoundException {
Class.forName("com.mysql.cj.jdbc.Driver").newInstance(); // 現代驅動類名
url = "jdbc:mysql://localhost/" + dbName +
"?user=root&password=" + password +
"&useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=UTC";
conn = DriverManager.getConnection(url);
stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
}
public ResultSet selectLog(String sql) throws SQLException {
buildConnection();
rs = stmt.executeQuery(sql);
return rs;
}
public void updateLog(String sql) throws SQLException {
buildConnection();
stmt.executeUpdate(sql);
}
public void close() throws SQLException {
if (rs != null) rs.close();
if (stmt != null) stmt.close();
if (conn != null) conn.close();
}
}
| 維度 | 現狀 | 風險/改進 |
|---|---|---|
| 連接管理 | 每次操作重新建連 | 極度低效,應引入連接池(HikariCP/Druid) |
| 異常處理 | 吞沒異常 catch {} | 導致故障靜默失敗,必須拋出或記錄日志 |
| SQL 注入 | 直接拼接 SQL 字串 | 高危,必須使用 PreparedStatement |
| 資源釋放 | 手動 close,無 finally/try-with-resources | 異常路徑易洩漏,改用 try-with-resources (Java 7+) |
| 字符集 | gb2312 | 建議 utf8mb4 支持完整 Unicode(含 Emoji) |
| 驅動類 | org.gjt.mm.mysql.Driver | 舊版驅動,現代用 com.mysql.cj.jdbc.Driver (MySQL 5.1+ / 8.0+) |
// 使用連接池 + PreparedStatement + try-with-resources
public class ModernMySQLDao {
private final DataSource dataSource; // 注入 HikariDataSource
public List<Map<String, Object>> query(String sql, Object... params) {
try (Connection conn = dataSource.getConnection();
PreparedStatement ps = conn.prepareStatement(sql)) {
for (int i = 0; i < params.length; i++) ps.setObject(i + 1, params[i]);
try (ResultSet rs = ps.executeQuery()) {
ResultSetMetaData meta = rs.getMetaData();
int cols = meta.getColumnCount();
List<Map<String, Object>> list = new ArrayList<>();
while (rs.next()) {
Map<String, Object> row = new HashMap<>();
for (int i = 1; i <= cols; i++) row.put(meta.getColumnLabel(i), rs.getObject(i));
list.add(row);
}
return list;
}
} catch (SQLException e) {
throw new RuntimeException("Query failed: " + sql, e);
}
}
}
mysql:mysql-connector-java:8.0.33 + com.zaxxer:HikariCP:5.0.1spring.datasource.hikari.* 微調池參數