JPA Enum ORDINAL vs STRING

java orm jpa enums eclipselink

22774 观看

8回复

199 作者的声誉

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

@Enumerated(EnumType.ORDINAL)

要么

@Enumerated(EnumType.STRING)

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

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

作者: jst99 的来源 发布者: 2011 年 7 月 22 日

回应 (8)


15

495207 作者的声誉

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

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

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

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

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

作者: Bozho 发布者: 22.07.2011 01:51

63

304062 作者的声誉

决定

我总是去STRING

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

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

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

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

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

UPDATE table SET enum_column = 'NEW_ENUM_NAME' where enum_column = 'OLD_ENUM_NAME';
作者: Bohemian 发布者: 22.07.2011 01:58

-4

3 作者的声誉

您真的确定您需要的是人类可读的数据库吗?存储字符串值是浪费空间。可读性的唯一妥协可能是使用@Enumerated(STRING)和地图数据库列作为ENUM(如果你使用的是mysql ...我认为其他dbms有类似的东西)但是当你必须更改枚举名称时真的很痛苦。

作者: Lothruin 发布者: 27.01.2012 12:04

0

1 作者的声誉

这取决于你的应用程序,如果你有更多机会使用String类型添加更多枚举,如果有更多的机会你将更改你的枚举名称使用Ordinal。

作者: samid hamza 发布者: 08.04.2017 03:12

3

821 作者的声誉

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

举例:

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

public enum UserStates { ACTIVE, DELETED, PENDING }

但现在,你有一个枚举,用于保存太阳系中的种植体(最佳使用@Enumerated(EnumType.STRING)):

public enum Planets {MERCURY,VENUS,EARTH,MARS,JUPITER,SATURN,URANUS,NEPTUNE,PLUTO,NINE}

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

您可以重新排序Plantes,@Enumerated(EnumType.STRING)因为您的Planet与枚举名称相关联,而不是枚举顺序。

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

字符串类型在数据库中更易读,但比有序数据的大小更多。如果数据库被更多客户使用,也许是有用的,但是最好有一个好的软件文档,而不是“EARTH”比“4”节省1000倍

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

Planets
------------
ID | Name |
------------
1 | EARTH
2 | EARTH
3 | MARS
4 | EARTH
作者: Genaut 发布者: 21.07.2017 06:20

2

6624 作者的声誉

这是一个很好的问题。在过去我使用String但今天我的偏好通常是Ordinal。

String的主要缺点是DBA。使用String,他们不知道列的可能值是什么,因为此信息位于应用程序代码中。DBA只能对表中存在的信息分组的可能值有所了解,但他永远不会确定其他可能的值或是否添加了新值,直到应用程序将它们插入到表中。

在Ordinal你有同样的问题。但是我对Ordinal的偏好是DBA问题的解决方案,这对数据库来说似乎很自然。您创建一个新表以在数据库上显示Enumerator的可能值,并在列(序数枚举值)和此新表之间使用外键。此策略在此处进行了描述和实施。

关于有人可以重新排序枚举器并破坏系统的问题,一个简单的单元测试可以解决这个问题,并保证没有好的警告就没人会重新排序。重命名Enumerator时,同样的想法是有效的。因此,意外地重命名(在String上)或重新排序(在Ordinal上)对于String或Ordinal方法来说并不是一个强有力的参数。

顺便说一句,开发人员更有必要重命名而不是重新排序枚举器,所以这是使用Ordinal的另一个积极点。

因此,通过这种方法,您可以解决Ordinal的主要问题(现在,可读),信息将占用数据库上较少的空间,您的DBA会很高兴。

作者: Dherik 发布者: 12.01.2018 03:57

0

18 作者的声誉

这里有很多好建议,但我只想添加一些我还没看到的东西:

无论您选择何种解决方案,都不要忘记在枚举类的顶部添加一个大胖警告,说明应该使用哪个。希望其他开发人员会看到你已经完成了这个并使用相同的方法来保存枚举。

作者: Steven B 发布者: 18.04.2019 12:21

0

155 作者的声誉

我更喜欢EnumType.STRING。EnumType.ORDINAL的缺点是时间的影响以及将枚举保持在逻辑顺序的愿望。使用EnumType.ORDINAL时,必须将任何新的枚举元素添加到列表的末尾,否则您将意外更改所有记录的含义。请检查以下链接:https//tomee.apache.org/examples-trunk/jpa-enumerated/

作者: Mendon Ashwini 发布者: 22.05.2019 07:21
32x32