核心映射表 (MySQL 8.0 / Connector/J 8.0 基準)
| MySQL 類型 | 顯示長度 | Java 類型 (推薦) | JDBC Type (java.sql.Types) | 備註 |
| VARCHAR(n) | n | String | VARCHAR (12) | n ≤ 65535,utf8mb4 實際字節 ≤ 65532 |
| CHAR(n) | n | String | CHAR (1) | 固定長度,右填充空格 |
| TINYTEXT | 255 | String | VARCHAR (-1 / LONGVARCHAR) | |
| TEXT | 65,535 | String | LONGVARCHAR (-1) | |
| MEDIUMTEXT | 16,777,215 | String | LONGVARCHAR (-1) | |
| LONGTEXT | 4,294,967,295 | String | LONGVARCHAR (-1) | JDBC 獲取用 getClob/getString |
| TINYINT | 3 | Integer / Boolean | TINYINT (-6) | Boolean 映射需 tinyInt1isBit=false |
| SMALLINT | 5 | Integer | SMALLINT (5) | |
| MEDIUMINT | 8 | Integer | INTEGER (4) | JDBC 無 MEDIUMINT 常量 |
| INT / INTEGER | 10 | Integer / Long | INTEGER (4) | Long 防溢出 (無符號 > 21億) |
| BIGINT | 20 | Long / BigInteger | BIGINT (-5) | 無符號需 BigInteger |
| FLOAT | 4+8 | Float | FLOAT (7) | 單精度,約 7 位有效數字 |
| DOUBLE | 22 | Double | DOUBLE (8) | 雙精度,約 15 位有效數字 |
| DECIMAL(p,s) | p | BigDecimal | DECIMAL (3) | 精確計算必須用 BigDecimal |
| BIT(n) | n | boolean / byte[] | BIT (-7) | BIT(1) 常映射 boolean |
| DATE | 10 | LocalDate / java.sql.Date | DATE (91) | Java 8+ 用 LocalDate |
| TIME | 8 | LocalTime / java.sql.Time | TIME (92) | Java 8+ 用 LocalTime |
| DATETIME | 19 | LocalDateTime / Timestamp | TIMESTAMP (93) | 無時區,5.6.4+ 支援毫秒 |
| TIMESTAMP | 19 | Instant / Timestamp | TIMESTAMP (93) | 有時區,UTC 存儲,自動轉換 |
| YEAR | 4 | Integer / Year | DATE (91) / INTEGER | MySQL 8.0 移除 YEAR(2) |
| BLOB 系列 | - | byte[] / Blob | BLOB (-4) / VARBINARY | 大對象用 getBlob/getBytes |
| JSON | - | String / JsonNode | VARCHAR / OTHER | 8.0 原生,建議 String 存儲 |
| ENUM/SET | - | String | VARCHAR / OTHER | 應用層建議用 Enum 類型 |
關鍵映射決策點
1. TINYINT(1) → Boolean 還是 Integer?
# 連接串參數控制
tinyInt1isBit=true # 默認 true:TINYINT(1) → Boolean
tinyInt1isBit=false # TINYINT(1) → Integer (推薦,避免 ORM 映射混淆)
2. 無符號類型處理
- MySQL
INT UNSIGNED 範圍 0 ~ 42.9 億,超過 Java Integer.MAX_VALUE (21.4 億)
- 映射策略:
- 寫入:應用層校驗範圍,或用
UNSIGNED 列配合 Long
3. 日期時間類型與時區
| 類型 | 時區行為 | Java 8+ 推薦 | 連接串建議 |
| DATETIME | 無時區,存什麼取什麼 | LocalDateTime | serverTimezone=UTC |
| TIMESTAMP | 存儲 UTC,讀取轉連接時區 | Instant / OffsetDateTime | serverTimezone=Asia/Shanghai |
4. DECIMAL 精確計算
// ❌ 錯誤:Double 精度丟失
double amount = rs.getDouble("price");
// ✅ 正確:BigDecimal 精確
BigDecimal amount = rs.getBigDecimal("price");
// JPA/Hibernate 映射
@Column(precision = 19, scale = 4)
private BigDecimal price;
5. BLOB 讀寫最佳實踐
// 寫入
try (InputStream is = new FileInputStream(file)) {
ps.setBinaryStream(1, is, file.length());
ps.executeUpdate();
}
// 讀取 (大對象分塊)
Blob blob = rs.getBlob("data");
try (InputStream is = blob.getBinaryStream();
OutputStream os = new FileOutputStream("out")) {
byte[] buf = new byte[8192];
int len;
while ((len = is.read(buf)) > 0) os.write(buf, 0, len);
}
連接串完整參數模板 (Connector/J 8.0+)
jdbc:mysql://localhost:3306/mydb?
useUnicode=true&
characterEncoding=utf8mb4&
serverTimezone=Asia/Shanghai&
tinyInt1isBit=false&
useSSL=false&
allowPublicKeyRetrieval=true&
nullNamePatternMatchesAll=true&
connectionCollation=utf8mb4_general_ci
總結
類型映射不是「照表對照」那麼簡單,**無符號溢出、時區轉換、精度丟失、Boolean 映射、大對象流式處理** 才是生產環境的真實挑戰。建立團隊統一的「類型映射規範文檔」,Code Review 時重點檢查,能消除 90% 的持久層 Bug。