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

The*_*heo 54 java jpa jpa-2.0

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

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

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

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

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

Kon*_*rus 46

就像你自己的问题所暗示的那样,关键是域名,而不是JPA.JPA只是一个框架,您可以(并且应该)以最适合您的问题的方式使用它.由于框架(或其限制)而选择次优解决方案通常是一个警告铃.

当我需要一套而不关心订单时,我会使用一个Set.当由于某种原因,订单很重要(有序列表,按日期排序等),那么a List.

你似乎是了如指掌之间的差异Collection,Set以及List.使用一个与另一个的唯一原因仅取决于您的需求.您可以使用它们向您的API(或您未来的自己)用户传达您的集合的属性(可能是微妙的或隐含的).

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

例如,当我看到a时List,我知道它以某种方式排序,并且重复项对于这种情况是可接受的或不相关的.当我看到a时Set,我通常希望它没有重复且没有特定的顺序(除非它是a SortedSet).当我看到a时Collection,我不希望它包含更多内容而不是包含一些实体.

关于列表排序......是的,它可以保留.即使它不是,你只是使用@OrderBy,它仍然是有用的.想一想默认情况下按时间戳排序的事件日志示例.人工重新排序列表毫无意义,但默认情况下排序仍然很有用.

  • 有一个案例我看到水是混乱的水是JSF.它不支持实体集合的Set接口,仅支持List.这在视图方面很好,但不是存储(通常).因此,在这种情况下视图必须是List,不幸地不断地转换为/从Set. (3认同)

u_b*_*u_b 28

我认为使用Set或List的问题要困难得多.至少当你使用hibernate作为JPA实现时.如果你在休眠中使用List,它会自动切换到"Bags"范例,其中存在重复的CAN.

而这个决定对hibernate执行的查询有重大影响.这里有一个小例子:

有两个实体,员工公司,典型的多对多关系.为了将这些实体映射到彼此,存在JoinTable(让我们称之为"employeeCompany").

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

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

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);
Run Code Online (Sandbox Code Playgroud)

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

delete from employeeCompany where employeeId = Joe AND company = companyXY;
Run Code Online (Sandbox Code Playgroud)

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

现在得出的结论是:

如果您在Employee/Company - Entities中选择Set而不是List,则表示您没有该问题,只执行了一个查询!

为什么呢?因为hibernate不再是一个袋子世界(如你所知,集合不允许重复),现在只能执行一个查询.

所以List和Sets之间的决定并不那么简单,至少在查询和性能方面如此!


Jam*_*mes 7

我一般使用List.我发现List API比Set更有用并且与其他库兼容.列表更容易迭代,并且通常对大多数操作和内存更有效.

关系不能重复并且通常不会被排序的事实不应该要求使用Set,您可以使用任何Collection类型对您的应用程序最有用.

这取决于你的模型,如果它是你要做的很多包含检查的东西,那么Set会更有效率.

您可以使用@OrderBy或@OrderColumn在JPA中订购关系.

请参阅 http://en.wikibooks.org/wiki/Java_Persistence/Relationships#Ordering

JPA通常不支持重复项,但某些映射(如ElementCollections)可能支持重复项.