有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

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

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

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

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

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


共 (6) 个答案

  1. # 1 楼答案

    我通常使用列表。我发现列表API比Set更有用,并且与其他库兼容。列表更容易迭代,而且对于大多数操作和内存来说通常效率更高

    一个关系不能有重复项,并且不是正常排序的,这一事实不需要使用集合,您可以使用对应用程序最有用的任何集合类型

    不过,这取决于你的模型,如果你要对它进行大量的包含检查,那么一个集合会更有效率

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

    看, http://en.wikibooks.org/wiki/Java_Persistence/Relationships#Ordering

    JPA通常不支持重复,但ElementCollections等一些映射可能支持重复

  2. # 2 楼答案

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

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

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

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

    因此,如果您现在决定从公司Y中删除员工,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);
    

    现在的问题是:为什么hibernate不仅执行这个查询

    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

    现在得出一个重要结论:

    如果在员工/公司实体中选择一个集合而不是列表,则不会出现该问题,只执行一个查询

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

    所以列表和集合之间的决定并不是那么简单,至少在查询和;表演

  3. # 3 楼答案

    我使用:

    • 集合:集合中的项目没有顺序且唯一时
    • 列表:当项目有订单时
  4. # 5 楼答案

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

  5. # 6 楼答案

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

    当我需要一个集合而从不关心顺序时,我使用Set。如果由于某种原因,顺序很重要(有序列表、按日期排序等),那么List

    你似乎很清楚CollectionSetList之间的区别。使用其中一个与另一个的唯一原因只取决于你的需求。您可以使用它们向API(或您未来的自己)的用户传达收藏的属性(可能是微妙的或隐含的)

    这与在代码的其他地方使用不同的集合类型遵循完全相同的规则。您可以对所有引用使用ObjectCollections,但在大多数情况下,您使用的是更具体的类型

    例如,当我看到一个List时,我知道它是以某种方式排序的,对于这种情况,重复项要么是可以接受的,要么是不相关的。当我看到一个Set时,我通常希望它没有重复项,也没有特定的顺序(除非它是一个SortedSet)。当我看到一个Collection时,除了包含一些实体之外,我对它没有任何期望

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