Hibernate 中,处理枚举类型的映射有几种方式,主要依赖于 @Enumerated 注解来指定枚举值如何保存到数据库。以下是常见的做法:

1. 使用 @Enumerated(EnumType.STRING)

这是推荐方式,将枚举的名字(字符串)保存到数据库中,可读性好,不容易出错。

public enum Status {
    ACTIVE, INACTIVE, DELETED
}

@Entity
public class User {

    @Id
    private Long id;

    @Enumerated(EnumType.STRING)
    private Status status;

    // getters and setters
}

数据库中存储: ACTIVE, INACTIVE 等字符串。

2. 使用 @Enumerated(EnumType.ORDINAL)

默认方式,保存的是枚举的序号(ordinal),不推荐,因为如果枚举顺序变化会导致数据错乱。

@Enumerated(EnumType.ORDINAL)
private Status status;

数据库中存储: 0, 1, 2,表示枚举的索引

3. 自定义枚举类型转换(使用 @Converter

更灵活的方式,适合枚举需要映射成自定义值,比如数据库中用 A, I, D 表示状态。

public enum Status {
    ACTIVE("A"), INACTIVE("I"), DELETED("D");

    private String code;

    Status(String code) {
        this.code = code;
    }

    public String getCode() {
        return code;
    }

    public static Status fromCode(String code) {
        for (Status s : Status.values()) {
            if (s.getCode().equals(code)) {
                return s;
            }
        }
        throw new IllegalArgumentException("Unknown code: " + code);
    }
}

转换器:

@Converter(autoApply = true)
public class StatusConverter implements AttributeConverter<Status, String> {

    @Override
    public String convertToDatabaseColumn(Status status) {
        return status != null ? status.getCode() : null;
    }

    @Override
    public Status convertToEntityAttribute(String dbData) {
        return dbData != null ? Status.fromCode(dbData) : null;
    }
}

总结建议:

方法优点缺点
EnumType.STRING可读性好、安全占用存储空间略大
EnumType.ORDINAL存储节省不稳定,容易出错
@Converter 自定义转换器可灵活映射任意值需要多写一点代码