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

0h4hbjxa  于 2023-03-16  发布在  Java
关注(0)|答案(6)|浏览(111)

您在JPA域模型中使用了以下哪些集合类型,为什么?

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

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

UPDATE我知道SetList之间的区别。List允许重复并且有顺序,而Set不能包含重复的元素并且不定义顺序。我在JPA的上下文中问这个问题。如果你严格遵循定义,那么你应该总是使用Set类型,因为您的集合存储在关系数据库中,您不能有重复项,并且您已经自己定义了顺序,即您的Java List中的顺序不一定保留在DB中。

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

omjgkv6w

omjgkv6w1#

就像你自己的问题所暗示的,关键是域,而不是JPA。JPA只是一个框架,你可以(也应该)以最适合你的问题的方式使用它。因为框架(或它的局限性)而选择一个次优的解决方案通常是一个警钟。
当我需要一个集合并且从不关心顺序时,我使用Set;当出于某种原因顺序很重要时(有序列表、按日期排序等),则使用List
您似乎很清楚CollectionSetList之间的区别。使用其中一个的唯一原因仅取决于您的需要。您可以使用它们向API的用户(或未来的自己)传达集合的属性(可能是微妙的或隐式的)。
这与在代码中其他地方使用不同集合类型遵循完全相同的规则,您可以使用ObjectCollections作为所有引用,但在大多数情况下,您使用的是更具体的类型。
例如,当我看到List时,我知道它是以某种方式排序的,重复项是可以接受的,或者与此情况无关;当我看到Set时,我通常希望它没有重复项,也没有特定的顺序(除非它是SortedSet);当我看到Collection时,除了包含一些实体外,我不希望它有任何其他内容。
关于列表排序......是的,它可以被保留。即使它不是,你只是使用@OrderBy,它仍然是有用的。考虑一下事件日志的例子,默认情况下按时间戳排序。人为地重新排序列表没有什么意义,但它仍然是有用的,它是默认排序的。

7kqas0il

7kqas0il2#

我认为使用Set或List的问题要困难得多。至少当你使用hib作为JPA实现时是这样。如果你在hib中使用List,它会自动切换到**“Bags”范例,在那里可能存在重复项。
这个决定对Hibernate执行的查询有很大的影响。这里有一个小例子:
有两个实体,employee
company**,这是一个典型的多对多关系。为了将这些实体相互Map,存在一个JoinTable(我们称之为“employeeCompany”)。
在两个实体(公司/员工)上选择数据类型List
因此,如果您现在决定从 CompanyXY删除Employee Joe,hib将执行以下查询:

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);

现在的问题是:为什么hib不只是执行那个查询呢

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

答案很简单(感谢尼拉夫·阿萨的博客):不可以。在一个包的世界里,删除所有并重新插入所有剩余的包是唯一正确的方法!请阅读该内容以了解更多信息。http://assarconsulting.blogspot.fr/2009/08/why-hibernate-does-delete-all-then-re.html
现在得出结论:

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

为什么呢?因为Hibernate不再是包的世界(如您所知,Sets不允许重复),现在只执行一个查询是可能的。
因此,在列表和集合之间做出选择并不那么简单,至少在查询和性能方面是这样!

35g0bw71

35g0bw713#

我通常使用List,我发现List API比Set更有用,与其他库的兼容性也更好,List更容易迭代,通常对大多数操作和内存更有效。
一个关系不能有重复项,并且通常不是有序的,这一事实不应该要求使用Set,您可以使用对应用程序最有用的任何Collection类型。
不过这取决于您的模型,如果您要对它进行大量的包含检查,那么Set会更高效。
您可以使用@OrderBy@OrderColumn在JPA中对关系进行排序。
请参见http://en.wikibooks.org/wiki/Java_Persistence/Relationships#Ordering
JPA中通常不支持重复,但某些Map(如ElementCollections)可能支持重复。

lawou6xi

lawou6xi4#

我用途:

  • Set:当集合中的项没有顺序并且唯一时
  • 列表:当物料有订单时
gg0vcinb

gg0vcinb5#

https://issues.apache.org/jira/browse/OPENJPA-710
在List和Set之间进行选择应该会影响查询发送到DB的方式。

vhipe2zx

vhipe2zx6#

我认为在使用Netbeans生成实体时使用Collection作为通用默认值是一个很好的起点,然后当您弄清楚您的模型实际上是什么并需要更多功能时,您可以轻松地更改它并保持向后兼容。

相关问题