核心 API 對照表
| 資料庫類型 | Java 類型 | ResultSet 方法 |
| INT, BIGINT, SMALLINT | int, long, short | getInt(), getLong(), getShort() |
| FLOAT, DOUBLE, DECIMAL | float, double, BigDecimal | getFloat(), getDouble(), getBigDecimal() |
| CHAR, VARCHAR, TEXT | String | getString() |
| DATE | java.sql.Date | getDate() |
| TIMESTAMP, DATETIME | java.sql.Timestamp | getTimestamp() |
| BLOB | InputStream / byte[] | getBinaryStream(), getBytes() |
| CLOB | Reader / String | getCharacterStream(), getString() |
完整讀取範例
try (Connection conn = DriverManager.getConnection(url, user, pass);
PreparedStatement ps = conn.prepareStatement("SELECT id, name, birth, salary, photo FROM users");
ResultSet rs = ps.executeQuery()) {
while (rs.next()) {
int id = rs.getInt("id");
String name = rs.getString("name");
Date birth = rs.getDate("birth");
BigDecimal salary = rs.getBigDecimal("salary");
Blob photo = rs.getBlob("photo");
// 日期格式化
String birthStr = (birth != null) ? new SimpleDateFormat("yyyy-MM-dd").format(birth) : "";
// Blob 處理
byte[] imgBytes = (photo != null) ? photo.getBytes(1, (int) photo.length()) : null;
System.out.printf("%d | %s | %s | %s | %d bytes%n", id, name, birthStr, salary, imgBytes?.length ?? 0);
}
}
關鍵注意事項
- 列名 vs 索引:推薦使用列名(
rs.getInt("id")),避免 SELECT 順序變更導致錯誤。
- NULL 值處理:
getInt() 遇 NULL 返回 0,無法區分。需先用 rs.wasNull() 或改用包裝類型邏輯判斷。
- 流式資源:
getBinaryStream()/getCharacterStream() 返回的流需在 finally 或 try-with-resources 中關閉。
- 游標方向:預設
TYPE_FORWARD_ONLY,若需隨機訪問建立 Statement 時指定 ResultSet.TYPE_SCROLL_INSENSITIVE。
- 大數據量:MySQL 需設定
stmt.setFetchSize(Integer.MIN_VALUE) 避免一次性載入全部結果導致 OOM。
進階技巧
- 使用
ResultSetMetaData 動態獲取列類型名稱,構建通用映射邏輯。
- 搭配
RowMapper (Spring JdbcTemplate) 或 ORM 框架減少樣板代碼。