JPA Enum ORDINAL vs STRING

jst*_*t99 39 java orm enums jpa eclipselink

可以使用其中任何一个在JPA中定义枚举

@Enumerated(EnumType.ORDINAL)
Run Code Online (Sandbox Code Playgroud)

要么

@Enumerated(EnumType.STRING)
Run Code Online (Sandbox Code Playgroud)

我想知道这两个定义的优点和缺点是什么?

我听说ORDINAL比使用EclipseLink的STRING表现更好(更快).
真的吗?

Boh*_*ian 65

我总是去STRING.

速度很少是最重要的问题 - 可读性和可维护性重要.

我使用STRING是因为手动检查数据库中的行要容易得多,但更重要的是,我可以做两件事,无需触及数据库,ORDINAL无法处理:

  1. 我可以改变我的枚举顺序
  2. 我可以在枚举列表的中间插入新的枚举

这两个更改都将改变数据库中已使用的枚举的序数值,因此如果您正在使用,则会破坏现有数据ORDINAL.

如果更改枚举值(不常见),处理它很简单:

UPDATE table SET enum_column = 'NEW_ENUM_NAME' where enum_column = 'OLD_ENUM_NAME';
Run Code Online (Sandbox Code Playgroud)

  • 另一方面,你不能重命名你的枚举.;)我不会说有一个首选的. (7认同)
  • 确保你可以:`UPDATE table SET enum_column = 'NEW_ENUM' where enum_column = 'OLD_ENUM' (2认同)
  • "灾难性"是一个过于情绪化的术语来描述重命名枚举 - 请参阅简单处理的答案. (2认同)

Boz*_*zho 16

它可能ORDINAL更有效,但那是次要的.有一些缺点ORDINAL:

  • 它在数据库中的可读性较差
  • 如果重新排序枚举定义,则数据库将不一致.

随着STRING你不能重命名枚举.

选择其中一个并在整个应用程序中使用它 - 保持一致.

如果您的数据库将被其他客户端/语言使用 - 使用STRING它,它更具可读性.


Gen*_*aut 7

我更喜欢使用 ,Ordinal但这真的取决于使用

举例:

您有一个枚举,用于保存所有用户状态,在这种情况下,顺序无关紧要,将来您可以添加更多状态(最佳用途是@Enumerated(EnumType.ORDINAL)):

public enum UserStates { ACTIVE, DELETED, PENDING }
Run Code Online (Sandbox Code Playgroud)

但是现在,您有了一个枚举,以保存太阳系中的植物(最佳用途@Enumerated(EnumType.STRING)):

public enum Planets {MERCURY,VENUS,EARTH,MARS,JUPITER,SATURN,URANUS,NEPTUNE,PLUTO,NINE}
Run Code Online (Sandbox Code Playgroud)

现在认为您想对行星重新排序,但@Enumerated(EnumType.ORDINAL)您不能,因为您的数据库无法知道 Java 文件中的新顺序。

您可以使用重新排序您的 Plantes,@Enumerated(EnumType.STRING)因为您的 Planet 链接到枚举名称,而不是枚举顺序。

无论如何,您可以修改您的@Enumerated(EnumType.ORDINAL)枚举,因为它们与订单相关联,但您不能更改您的@Enumerated(EnumType.STRING)枚举,因为它们会像新枚举一样使用。

字符串类型在数据库中更具可读性,但会比有序数据占用更多的大小。如果数据库被更多的客户使用,也许会有用,但最好有一个好的软件文档,而不是保存 1000 次“地球”而不是“4”

USERSTATE
------------
ID | STATE |
------------
1 | 1
2 | 2
3 | 1

Planets
------------
ID | Name |
------------
1 | EARTH
2 | EARTH
3 | MARS
4 | EARTH
Run Code Online (Sandbox Code Playgroud)