您使用哪种Java类型进行JPA集合,为什么?

2022-08-31 13:41:00

在 JPA 域模型中使用以下哪些集合类型以及原因:

  • java.util.Collection
  • java.util.List
  • java.util.Set

我想知道这是否有一些基本规则。

更新我知道 a 和 a 之间的区别。A 允许重复项并具有顺序,而 a 不能包含重复元素,并且不定义顺序。我在JPA的背景下提出这个问题。如果你严格遵循定义,那么你应该总是使用类型,因为你的集合存储在关系数据库中,在那里你不能有重复项,并且你自己定义了一个顺序,即Java中的顺序不一定保留在数据库中。SetListListSetSetList

例如,大多数时候我使用该类型,而不是因为它有顺序或允许重复(无论如何我都不能有),因为我的组件库中的某些组件需要一个列表。List


答案 1

就像你自己的问题所暗示的那样,关键是领域,而不是JPA。JPA只是一个框架,你可以(也应该)以最适合你的问题的方式使用它。由于框架(或其局限性)而选择次优解决方案通常是一个警钟。

当我需要一套并且从不关心顺序时,我会使用.当由于某种原因顺序很重要(有序列表,按日期排序等)时,则为.SetList

您似乎很清楚 、 和 之间的区别。使用一个与另一个的唯一原因仅取决于您的需求。您可以使用它们向 API 的用户(或您未来的自己)传达集合的属性(可能是微妙的或隐式的)。CollectionSetList

这与在整个代码中的其他任何位置使用不同的集合类型完全相同。您可以使用 或 用于所有引用,但在大多数情况下,您使用更具体的类型。ObjectCollections

例如,当我看到 一个 ,我知道它以某种方式排序,并且重复项对于这种情况是可以接受的或无关紧要的。当我看到一个时,我通常期望它没有重复项,也没有特定的顺序(除非它是一个)。当我看到 一个 ,我不期望从它那里得到任何东西,除了包含一些实体。ListSetSortedSetCollection

关于列表排序...是的,它可以保存。即使它不是,你只是使用,它仍然有用。考虑一下默认情况下按时间戳排序的事件日志的示例。人为地对列表进行重新排序没有多大意义,但默认情况下对列表进行排序仍然很有用。@OrderBy


答案 2

我认为使用集合或列表的问题要困难得多。至少当您使用休眠作为 JPA 实现时。如果您在休眠状态下使用List,它会自动切换到“Bags”范式,其中可以存在重复项。

该决策对查询休眠执行有重大影响。下面是一个小例子:

有两个实体,员工公司,典型的多对多关系。为了将这些实体相互映射,存在一个JoinTable(我们称之为“employeeCompany”)。

在两个实体(公司/员工)上选择数据类型列表

因此,如果您现在决定从 CompanyXY 中删除 Employee Joe,则休眠将执行以下查询:

delete from employeeCompany where employeeId = Joe;
insert into employeeCompany(employeeId,companyId) values (Joe,CompanyXA);
insert into employeeCompany(employeeId,companyId) values (Joe,CompanyXB);
insert into employeeCompany(employeeId,companyId) values (Joe,CompanyXC);
insert into employeeCompany(employeeId,companyId) values (Joe,CompanyXD);
insert into employeeCompany(employeeId,companyId) values (Joe,CompanyXE);

现在的问题是:为什么休眠不仅执行该查询?

delete from employeeCompany where employeeId = Joe AND company = companyXY;

答案很简单(Nirav Assar在他的博客文章中有很多):它不能。在袋子的世界里,全部删除并重新插入所有剩余是唯一正确的方法!阅读该内容以获取更多说明。http://assarconsulting.blogspot.fr/2009/08/why-hibernate-does-delete-all-then-re.html

现在得出一个大结论:

如果您在员工/公司 - 实体中选择“集”而不是“列表”,则不会遇到该问题,并且只执行一个查询!

为什么呢?因为休眠不再处于包的世界中(如您所知,Sets不允许重复),并且现在只能执行一个查询。

因此,List和Sets之间的决策并不是那么简单,至少在查询和性能方面是这样!


推荐