在 Java(或其他語言)中使用 MySQL 的 ENUM 類型時,實體類的映射方式取決於你使用的 ORM 框架(如 MyBatis、Hibernate/JPA 等)。以下是幾種常見做法:
一、使用 JPA/Hibernate(推薦)
1. 定義枚舉類
public enum Gender {
MALE, FEMALE, OTHER
}
2. 實體類中使用
@Entity
@Table(name = "user")
public class User {
@Id
private Long id;
@Enumerated(EnumType.STRING) // 存儲為字符串 'MALE', 'FEMALE' 等
private Gender gender;
// getter/setter...
}
@Enumerated(EnumType.STRING):將枚舉存儲為字符串(對應 MySQL ENUM 的值)@Enumerated(EnumType.ORDINAL):按序號存儲(0,1,2...),不推薦,因為 MySQL 的 ENUM 是基於字符串的,且序號變更易出錯。
⚠️ 注意:MySQL 的
ENUM類型本質上是字符串集合,底層用數字索引優化存儲,但對外表現為字符串。所以建議用STRING方式映射。
二、使用 MyBatis
MyBatis 默認支持 Java 枚舉與數據庫字符串/整數的映射。
1. 枚舉定義(可選實現接口以增強控制)
public enum Status {
ACTIVE("active"),
INACTIVE("inactive");
private final String value;
Status(String value) {
this.value = value;
}
public String getValue() {
return value;
}
// 可選:根據數據庫值反向查找枚舉
public static Status fromValue(String value) {
for (Status s : values()) {
if (s.value.equals(value)) {
return s;
}
}
throw new IllegalArgumentException("Unknown status: " + value);
}
}
2. 實體類
public class User {
private Long id;
private Status status;
// getter/setter
}
3. MyBatis TypeHandler(可選但推薦)
如果你的枚舉使用自定義字符串值(如上面的 "active"),需要寫一個 TypeHandler:
@MappedTypes(Status.class)
public class StatusTypeHandler extends BaseTypeHandler<Status> {
@Override
public void setNonNullParameter(PreparedStatement ps, int i, Status parameter, JdbcType jdbcType) throws SQLException {
ps.setString(i, parameter.getValue());
}
@Override
public Status getNullableResult(ResultSet rs, String columnName) throws SQLException {
String value = rs.getString(columnName);
return value == null ? null : Status.fromValue(value);
}
// 其他重載方法...
}
然後在 MyBatis 配置中註冊,或在字段上使用 @Results / resultMap 指定 typeHandler。
如果枚舉名和數據庫值一致(如
ACTIVE↔'ACTIVE'),MyBatis 默認能自動轉換,無需 TypeHandler。
三、注意事項
- MySQL ENUM 的限制:
- 值必須預先定義,不能動態擴展。
- 修改 ENUM 列(增刪值)可能鎖表,影響性能。
- 排序按定義順序,不是字母序。
- 替代方案建議: 很多團隊避免使用 MySQL 的
ENUM,而改用:
VARCHAR+ 應用層枚舉校驗- 單獨的字典表(更靈活,支持國際化等)
這樣實體類直接用枚舉即可,數據庫無耦合。
總結
|
場景
|
實體類處理方式
|
|
JPA/Hibernate
|
|
|
MyBatis(簡單)
|
Java enum 名 = DB 值,自動映射
|
|
MyBatis(複雜值)
|
自定義 |
|
最佳實踐
|
考慮不用 MySQL ENUM,改用 VARCHAR + 枚舉
|