【问题标题】:Enum field in JPA EntityJPA 实体中的枚举字段
【发布时间】:2013-01-04 10:24:26
【问题描述】:

我觉得这个问题有点愚蠢,但我找不到任何简单的答案。

以这个简单的实体为例:

@Entity
@Table( name="clienti" )
public class Cliente implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private Long id;

    private String nome;

    private String cognome;

//...
}

它代表一个人,所以我想添加一个“gender”属性。

它将是“男性”或“女性”。那又怎样?

我可以使用字符串,记住“m”代表男性,“f”代表女性。

或者我可以使用布尔值“isMale”,真或假。

但是,我认为无论哪种情况,Hibernate 纯粹主义者都不会高兴 :)

谷歌搜索了一下,我发现最好的做法是使用 枚举

我对如何使用它有点困惑。你能帮我举个例子吗?

【问题讨论】:

    标签: hibernate jpa enums


    【解决方案1】:

    您可以将enum 映射到String 或序数。映射到String 是更便携的方法,因为映射将在更改枚举顺序后继续存在。

    使用您的示例:

    @Entity
    @Table( name="clienti" )
    public class Cliente implements Serializable {
    
    ...
        @Enumerated(EnumType.STRING)
        private Gender gender;
    ...
    }
    

    字符串映射将使用枚举类型的简单名称,因此您将在 DB 中有两个可能的值 - 'Male' 和 'Female'

    public enum Gender { MALE, FEMALE }
    

    持久性提供程序负责映射,因此在您的代码中,您可以继续使用 Gender 枚举,而不必担心字符串或序数。

    【讨论】:

    • 我认为这正是我正在寻找的。我只是想在接受你的回答之前尝试一下。只有一件事......“性别”枚举必须在自己的文件中,不是吗?
    • @FabioB。 - 如果您只想将性别公开给客户端对象,它也可以是一个内部类,但总的来说,我建议将其定义为顶级枚举。
    • 如果您计划将来更改值名称,您还应该考虑使用EnumType.ORDINAL
    • EnumType.ORDINAL 是一个非常糟糕的主意。如果您不小心从中间而不是结尾添加或删除了 ENUM,它将破坏您的输出,因为 ORDINAL 使用声明枚举的逻辑顺序。避免它。
    【解决方案2】:
    public enum Gender{ 
        MALE, FEMALE 
    }
    
    
    
    @Entity
    @Table( name="clienti" )
    public class Cliente implements Serializable {
    ...
    
    // **1 case** - If database column type is number (integer) 
    // (some time for better search performance)  -> we should use 
    // EnumType.ORDINAL as @O.Badr noticed. e.g. inserted number will
    // index of constant starting from 0... in our example for MALE - 0, FEMALE - 1.
    // **Possible issue (advice)**: you have to add the new values at the end of
    // your enum, in order to keep the ordinal correct for future values.
    
    @Enumerated(EnumType.ORDINAL)
        private Gender gender;
    
    
    // **2 case** - If database column type is character (varchar) 
    // and you want to save it as String constant then ->
    
    @Enumerated(EnumType.STRING)
        private Gender gender;
    
    ...
    }
    
    // in all case on code level you will interact with defined 
    // type of Enum constant but in Database level
    

    第一种情况(EnumType.ORDINAL)

    ╔════╦══════════════╦════════╗
    ║ ID ║    NAME      ║ GENDER ║
    ╠════╬══════════════╬════════╣
    ║  1 ║ Jeff Atwood  ║    0   ║
    ║  2 ║ Geoff Dalgas ║    0   ║
    ║  3 ║Jarrod Jesica ║    1   ║
    ║  4 ║ Joel Lucy    ║    1   ║
    ╚════╩══════════════╩════════╝
    

    第二种情况(EnumType.STRING)

    ╔════╦══════════════╦════════╗
    ║ ID ║    NAME      ║ GENDER ║
    ╠════╬══════════════╬════════╣
    ║  1 ║ Jeff Atwood  ║  MALE  ║
    ║  2 ║ Geoff Dalgas ║  MALE  ║
    ║  3 ║Jarrod Jesica ║ FEMALE ║
    ║  4 ║ Joel Lucy    ║ FEMALE ║
    ╚════╩══════════════╩════════╝
    

    【讨论】:

    • 如果你选择一个字符串类型并且想要输出小写,那可以实现吗?如何使用@Enumerated(EnumType.STRING)?
    猜你喜欢
    • 1970-01-01
    • 2015-08-22
    • 1970-01-01
    • 2018-05-04
    • 1970-01-01
    • 1970-01-01
    • 2012-01-01
    • 2022-07-21
    • 1970-01-01
    相关资源
    最近更新 更多