可以使用以下任一方法在JPA中定义枚举

@Enumerated(EnumType.ORDINAL)

要么

@Enumerated(EnumType.STRING)

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

我听说ORDINAL的性能比EclipseLink的STRING更好(更快)。

真的吗?

我认为ORDINAL默认情况下不使用@Enumerated批注

在JPA 2.1中,您可以指定@Converter并允许映射到字符串或其他数据类型,该类型可以是简单/简短,也可以是长/复杂。

我总是去STRING。

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

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

我可以更改枚举的顺序

我可以在枚举列表的中间插入新的枚举

这两个更改都将更改数据库中已在使用的枚举的序数值,从而在使用ORDINAL时破坏现有数据。

如果更改枚举值(不是很常见),则处理起来很简单:

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

另一方面,您不能重命名枚举。 ;)我不会说有一个首选的。

确保可以:`UPDATE table SET enum_column = NEW_ENUM其中enum_column = OLD_ENUM

重命名Enums就像重命名表或表中的列一样会带来灾难性的后果,它已经产生了长远的不平凡的影响,我不认为这是个问题,因为这样的大变化将被仔细考虑。您更有可能添加新的枚举而不删除或重命名它们,而不必担心更改序数位置对于外部代码更为重要,因为外部代码在编译时无法检查,重命名可以。最后,客户端代码不必关心您使用哪个代码,名称更易于维护。

如果有人不知道该数据库中使用了枚举名称,则不会。我会说我重命名枚举的次数要比重新排序的次数多。而且您也可以使用常规的UPDATE查询

"灾难性"这个词太令人动容,无法描述重命名枚举-有关简单处理,请参见答案。

如何在数据库和代码中同时更新enum名称?

@Sangdol将是一个释放任务:重命名枚举后,在释放代码时,运行sql脚本以更新所使用的枚举名称:update mytable set myenumcol = newname where myenumcol = oldname

Ordinal的优点是始终使用@OrderBy,而使用String时,排序是按字母顺序进行的(这里我是说db SELECT语句)。

@ 1in9ui5t有趣的一点是,尽管大多数数据库都有按枚举排序的方式。特别是,如果您也将该列也实现为mysql枚举,则按枚举顺序排序,如果可以使用纯字符串,则可以order by find_in_set(mycolumn, ENUM_NAME_1, ENUM_NAME_2, ...)(有点难看,但足够简单)

@Bohemian我不知道数据库中的ENUM类型。这样就解决了订购问题。只需在列定义中包括Enum值即可。

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

它在数据库中不太可读

如果您对枚举定义重新排序,则数据库将不一致。

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

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

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

我更喜欢使用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.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

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

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

在Ordinal中,您有同样的问题。但是我更喜欢Ordinal来解决数据库似乎很自然的DBA问题。您创建一个新表以在数据库上显示枚举数的可能值,并在列(常规枚举值)和此新表之间使用外键。在此描述和实施此策略。

关于有人可以对Enumerator进行重新排序并破坏系统的问题,一个简单的单元测试可以解决此问题,并确保没有人在没有良好警告的情况下对其进行重新排序。在重命名枚举器时,同样的想法是有效的。因此,意外地重命名(在String上)或重新排序(在Ordinal上)并不是针对String或Ordinal方法的强烈反对。

顺便说一句,开发人员比重命名Enumerator更需要重命名,因此这是使用Ordinal的另一个积极方面。

因此,使用这种方法,您可以解决Ordinal的主要问题(现在已经可以读取)了,该信息将在数据库上占用更少的空间,并且DBA会很高兴。

我更喜欢EnumType.STRING。

EnumType.ORDINAL的一个缺点是时间的影响以及保持枚举逻辑顺序的愿望。使用EnumType.ORDINAL必须将任何新的枚举元素添加到列表的末尾,否则您将不小心更改所有记录的含义。

请检查此链接:

https://tomee.apache.org/examples-trunk/jpa-enumerated/

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

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

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

您真的确定需要人类可读的数据库吗?

存储字符串值是浪费空间。可读性的唯一折衷办法是使用@Enumerated(STRING)并将map数据库列作为ENUM使用(如果您使用的是mysql ...我想其他dbms也有类似的用法),但是当您必须更改枚举名称时,这确实很痛苦。

(讽刺评论警告)是的,这样更好,因为必须仔细检查代码才能找到该序数值的实际含义。...哦,别忘了排序-当有人在枚举的中间/顶部插入一个新值时,效果很好。不要让实现决定设计。 @Enumerated(ORDINAL)被认为是有害的

可维护性和可读性比您所说的重要得多。这些东西(空间)在服务速度和内存消耗方面几乎完全没有成本。当您最终由于此类问题而解决问题时,这会立即使您付出代价(比空间大)。

@earcam(讽刺的回答),您随时可以在列上添加评论,并在需要时随时阅读。这难读吗?恕我直言,这张票没有回答这个问题,两种情况各有利弊

@dwilda哈哈,很公平。但是可以肯定的是,基数+(复合)索引可以缓解任何性能问题...不匹配已经很严重了?

java emun ordinal_关于Java:JPA枚举ORDINAL与STRING相关推荐

  1. Java、Mysql、MyBatis 中枚举 enum 的使用

    From: https://yulaiz.com/java-mysql-enum/ Java 和 MySql 中都有枚举的概念,合理的使用枚举,可以让代码阅读和数据库数据查询更加直观.高效.那么我们怎 ...

  2. enum java 比较_Kotlin与Java比较:枚举类

    前言 Kotlin作为JVM系的语言,起源于Java又不同于Java.通过在语言层面比较两者的区别,可以使得开发者能够快速学习,融会贯通. 枚举使用场景 使用枚举的场景非常明确,即只要一个类的对象是有 ...

  3. java 动态更新_java动态更新枚举类

    工作中遇到需要对枚举类的值进行动态更新 手动改不现实也不方便 现记录下来方便以后学习使用 1.在工程utils包中添加动态更新枚举类得工具类(根据自己得项目,放到指定位置调用就可以) 2.一开始陷入了 ...

  4. JAVA学习日记(18)——反射和枚举

    1.反射 1.1 定义 Java的反射(reflection)机制是在运行状态下,对于任何一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意属性和方法,既然能够拿到那么我们 ...

  5. 重新认识java(十) ---- Enum(枚举类)

    有的人说,不推荐使用枚举.有的人说,枚举很好用.究竟怎么使用,如何使用,仁者见仁智者见智.总之,先学会再说~ 为什么要引入枚举类 一个小案例 你写了一个小程序,不过好久不用了,突然有一天,你想使用一下 ...

  6. Java IO流 、 Properties 、 枚举

    一.概述 IO流流动的是数据 --- 用于传输数据的API. InputStream\OutputStream   ---   输入输出流 根据流的传输方向分类 :  当数据从外部流入程序时  : 输 ...

  7. java中的jpa_JPA教程–在Java SE环境中设置JPA

    java中的jpa JPA代表Java Persistence API,它基本上是一个规范,描述了一种将数据持久存储到持久存储(通常是数据库)中的方法. 我们可以将其视为类似于Hibernate之类的 ...

  8. JPA教程–在Java SE环境中设置JPA

    JPA代表Java Persistence API,它基本上是一个规范,描述了一种将数据持久存储到持久存储(通常是数据库)中的方法. 我们可以将其视为类似于Hibernate的 ORM工具的东西,除了 ...

  9. java后端参数默认值添加枚举_利用自定义Validator和枚举类来限定接口的入参

    趁热记录下,给未来的自己 0. 前言 Spring Validation 作为一个参数验证框架,本身提供的注解已经很强大了,能覆盖大部分业务场景需求,比如:@NotNull, @NotBlank, @ ...

  10. JAVA第四次作业——使用枚举类对扑克牌建模

    0x00 简述 使用枚举类型对一副扑克牌(52张牌,不包括大小王)建模: 一副扑克牌有四种花色(Suit):HEART,SPADE,DIAMOND,CLUB: 有十三种等级(Rank):ACE,TWO ...

最新文章

  1. 手机黑产为啥没支付宝的份?官方回应:犯罪分子无法突破人脸识别
  2. JAVA后端开发规范
  3. python3 time
  4. SpringBoot中使用thymeleaf的trim方法进行判断字符串是否相等
  5. bits/stdc++.h头文件总结
  6. 离线安装Cloudera Manager 5和CDH5(最新版5.9.3) 完全教程(七)界面安装
  7. C++ 大话数据结构 09: 中缀表达式 转后缀表达式 计算器
  8. protel PCB布线精华文章
  9. 数仓大法好!跨境电商 Shopee 的实时数仓之路
  10. 电池供电的电容麦_电容麦一定需要幻象电源吗 幻象电源的作用是什么
  11. python sendto(右键发送文件到执行的bat)功能的实现
  12. 【CNN】四张图彻底搞懂CNN反向传播算法(通俗易懂)
  13. python画图代码乔治-2020阅读书单
  14. 大数据学习计划(不断改善)(小白入门指南)
  15. 嵌入式系统(二):ARM芯片及体系架构(上)
  16. 开关电源补偿环路设计(1):基础部分-以Buck 为例
  17. 淘汰国足后反被附体?伊朗0:3不敌日本无缘决赛
  18. NC打开节点报该产品的用户数已达到产品授权数的解决方法
  19. 算法分析与设计|主要内容整理
  20. 修改计算机名并加入工作组

热门文章

  1. FC6000蒸汽气体热水液体智能流量积算仪特点
  2. 阿里云centos7 服务器XorDDoS木马查杀
  3. 如何生成SSH key?
  4. 基于单片机仿指针显示的电子时钟设计(毕业设计资料)
  5. windows x64和x86的区别
  6. excel max函数的使用
  7. Linux重要命令-locat
  8. mysql网络投票系统设计_学生在线投票表决系统设计与开发(JSP,MySQL)
  9. 解决zabbix自动发现主机后主机名称是IP地址的问题
  10. winform DataGridView 文本居中