傳統 JDBC 查詢需針對每張資料表寫對應的 ResultSet 解析邏輯,資料庫結構變更時維護成本高。本文示範利用 ResultSetMetaData 動態取得欄位資訊,搭配 List<Object[]> 通用資料結構,實現單一方法查詢任意資料表。
ResultSetMetaData.getColumnCount() 取得欄位數ResultSetMetaData.getColumnName(i) / getColumnTypeName(i) 取得欄位名稱與型別Object[] 陣列儲存,整個結果集為 List<Object[]>import java.math.BigDecimal;
import java.sql.*;
import java.util.*;
public class GenericJdbcDao {
private final String url;
private final String username;
private final String password;
public GenericJdbcDao(String url, String username, String password) {
this.url = url;
this.username = username;
this.password = password;
try {
// Oracle 範例,依實際驅動調整
Class.forName("oracle.jdbc.driver.OracleDriver");
} catch (ClassNotFoundException e) {
throw new RuntimeException("JDBC 驅動載入失敗", e);
}
}
private Connection getConnection() throws SQLException {
return DriverManager.getConnection(url, username, password);
}
/**
* 通用查詢,回傳 List<Object[]>,每個 Object[] 代表一列資料
*/
public List
query(String sql, Object... params)。RowMapper<T> 介面將 Object[] 映射為領域物件(類 Spring JdbcTemplate)。ROWNUM、MySQL LIMIT、SQL Server OFFSET/FETCH 方言抽象。| 優點 | 缺點/注意 |
|---|---|
| 單一方法支援任意查詢,減少樣板碼 | 失去編譯期型別檢查,執行期才發現型別不符 |
| 適合動態報表、匯出、通用查詢介面 | getObject() 對大型資料型別 (BLOB/CLOB) 效能較差,需分開處理 |
| 快速原型開發、資料庫管理工具 | 不適合高頻核心業務交易,建議改用 ORM 或強型別 DAO |
ResultSetMetaData 提供資料庫結構的運行期反射能力,配合通用集合結構可快速構建動態查詢功能。但生產核心業務仍建議採用強型別映射 (JPA/Hibernate/MyBatis/JdbcTemplate) 以獲得編譯期安全與效能優化。