JPA 枚举 ORDINAL 与 STRING

发布于 2024-11-25 19:07:15 字数 243 浏览 1 评论 0原文

可以使用其中之一在 JPA 中定义枚举

@Enumerated(EnumType.ORDINAL)

,或者

@Enumerated(EnumType.STRING)

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

我听说 ORDINAL 在 EclipseLink 中的性能比 STRING 更好(更快)。
这是真的吗?

It's possible to define enumerations in JPA using either

@Enumerated(EnumType.ORDINAL)

or

@Enumerated(EnumType.STRING)

I wonder what are advantages and disadvantages of those two definitions?

I heard that ORDINAL performs better (is faster) than STRING with EclipseLink.
Is that true?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

ㄟ。诗瑗 2024-12-02 19:07:16

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

It depends on your application, if there are more chances that you will add more enums use the String type, if there are more chances that you will change the name of your enums use Ordinal.

一抹苦笑 2024-12-02 19:07:16

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

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

Lots of good advice here, but I just wanted to add something I didn't see yet:

Regardless of the solution you choose, don't forget to add a big fat warning at the top of your enum class saying which should be used. Hopefully other developers will see you've done this and use the same method for saving the enum.

酒儿 2024-12-02 19:07:16

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

I would prefer EnumType.STRING.
A disadvantage of EnumType.ORDINAL is the effect of time and the desire to keep enums in a logical order. With EnumType.ORDINAL any new enum elements must be added to the end of the list or you will accidentally change the meaning of all your records.
please check this link:
https://tomee.apache.org/examples-trunk/jpa-enumerated/

乖乖兔^ω^ 2024-12-02 19:07:16

我会提出第三种可能性:通过 AttributeConverter 使用显式映射。这样您就可以摆脱更改 ORDINAL 顺序和重构 STRING 名称的问题。通过这种方式,您可以使用有意义的枚举值和紧凑而强大的存储。例如,我有一个带有值“EXPORT”和“IMPORT”的枚举,它们存储为“E”和“I”。如果有一天我决定将它们重构为“EXPORT_TYPE”和“IMPORT_TYPE”,JPA 存储不会受到影响。

I would throw in a third possibility: Use explicit mapping via AttributeConverter. This way you get rid of the problem with changing order for ORDINAL and with refactoring names for STRING. This way you can use meaningful enum values with compact and robust storage. For example I have an enum with values "EXPORT" and "IMPORT" which are stored as "E" and "I". If I one day decided to refactor them to "EXPORT_TYPE" and "IMPORT_TYPE", JPA storage is unaffected.

鱼窥荷 2024-12-02 19:07:16

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

Are you really sure that a human readable database is what you need?
Storing string value is a waste of space. The only compromise with readability could be use @Enumerated(STRING) and map database column as ENUM (if you are using mysql... I presume other dbms have something similar) but it's a real pain when you have to change enum names.

绝情姑娘 2024-12-02 19:07:15

我总是去 STRING

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

我使用 STRING 因为手动检查数据库中的行要容易得多,但更重要的是,我可以做两件事,而无需接触数据库,ORDINAL 不能句柄:

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

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

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

UPDATE table SET enum_column = 'NEW_ENUM_NAME' where enum_column = 'OLD_ENUM_NAME';

I always go STRING.

Speed is rarely the most important issue - readability and maintainability are more important.

I use STRING because it's a lot easier to manually inspect rows from the database, but more importantly, I can do two things, without touching the database, the ORDINAL can't handle:

  1. I can change the order of my enums
  2. I can insert new enums in the middle of the enum list

Both of these changes will alter the ordinal values of the enums already in use in the database, thus breaking existing data if you are using ORDINAL.

If you change an enum value (not that common), handling it is simple:

UPDATE table SET enum_column = 'NEW_ENUM_NAME' where enum_column = 'OLD_ENUM_NAME';
箜明 2024-12-02 19:07:15

ORDINAL 可能更高效,但这只是次要的。 ORDINAL 有一些缺点:

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

使用 STRING 您无法重命名枚举。

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

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

It's likely that ORDINAL is more efficient, but that's minor. There are a few downsides to ORDINAL:

  • it is less readable in the database
  • if you reorder your enum definitions the database will not be consistent.

With STRING you can't rename your enums.

Pick one of them and use it throughout the whole application - be consistent.

If your database is going to be used by other clients/languages - use STRING, it's more readable.

橘香 2024-12-02 19:07:15

我更喜欢使用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 文件中的新顺序。

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

无论如何,您可以修改您的 @Enumerated(EnumType.ORDINAL) 枚举,因为它们链接到订单,但您无法更改您的 @Enumerated(EnumType.STRING)枚举,因为它们会像新的枚举一样使用。

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

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

Planets
------------
ID | Name |
------------
1 | EARTH
2 | EARTH
3 | MARS
4 | EARTH

I prefer the use of Ordinal but this really depends on the use.

By example:

You have a enum, to save all your user states, in this case the order doesn't matter, and you can add more states in the future (Best use is @Enumerated(EnumType.ORDINAL)):

public enum UserStates { ACTIVE, DELETED, PENDING }

But now, you have an enum, to save the Plantes in the Solar System (Best use @Enumerated(EnumType.STRING)):

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

Now think that you want reorder your planets, with @Enumerated(EnumType.ORDINAL) you can't, because your database can't know the new order in your Java file.

You can reorder your Plantes using @Enumerated(EnumType.STRING) because your Planet is linked to the enum name, not the enum order.

Anyway, you can modify your @Enumerated(EnumType.ORDINAL)enums because they are linked to the order, but you can't change your @Enumerated(EnumType.STRING)enums because they will use like new enums.

String types are more readable in the Database, but will occupy more size than an ordinal data. Maybe are useful if the database is used by more clients, but it's better have a good documentation of the software than save 1000 times "EARTH" than "4"

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

Planets
------------
ID | Name |
------------
1 | EARTH
2 | EARTH
3 | MARS
4 | EARTH
眉目亦如画i 2024-12-02 19:07:15

这是一个好问题。过去我使用String,但今天我更喜欢使用Ordinal

对于 DBA 来说,字符串的主要缺点是。对于字符串,他们不知道该列的可能值是什么,因为此信息位于应用程序代码中。 DBA 只能对表中现有信息分组的可能值有一些了解,但在应用程序将它们插入表中之前,他永远无法确定其他可能值。

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

关于有人可能重新排序枚举器并破坏系统的问题,一个简单的单元测试可以处理这个问题,并保证没有人会在没有很好的错误的情况下重新排序它们。同样的想法也适用于重命名枚举器。因此,意外地重命名(在字符串上)或重新排序(在序数上)并不是反对字符串或序数方法的有力论据。

顺便说一句,在我看来,开发人员更有必要重命名而不是重新排序枚举器,因此我认为这是使用 Ordinal 的一个更积极的点。

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

This is a good question. In the past I used String but today my preference is to use Ordinal.

The main disadvantage for the String is for the DBAs. With the String they have no idea what are the possible values of the column, because this information is in the application code. The DBA only can have some idea about the possible values grouping the existent information on the table, but he will never be sure about the other possible values until the application insert them on the table.

In the Ordinal you have the same problem above. But my preference for Ordinal came to a solution to the DBA problem that seems natural to the database. You can create a new table to show the possible values of the Enumerator on database, with a foreign key between the column (ordinal enum value) and this new table. This strategy is described and implemented here.

About the problem that someone could reorder the Enumerator and break the system, a simple unit test can deal with this problem and guarantee that no one will reorder them without a very good error. The same idea is valid on renaming the Enumerator. So, renaming (on String) or reorder (on Ordinal) accidentally it is not really a strong argument against String or Ordinal approach.

By the way, for my perspective the developers have more necessity to rename than reorder an Enumerator, so I count this as one more positive point to use Ordinal.

So, with this extra table approach, you solve the main problem of the Ordinal (now, is readable) and the information will occupy less space on the database (and your DBA will be happy).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文