使用 Set 还是 List 的问题我认为比较难。尤其是在使用 hibernate 作为 JPA 实现时。如果在 hibernate 中使用 List,它会自动转换为“Bags”范式,其中可以存在重复项。
这个决定对 hibernate 执行的查询有重要影响。以下是一个小例子:
有两个实体,员工和公司,典型的多对多关系。为了将这些实体映射到彼此,存在一个 JoinTable(我们称之为“employeeCompany”)。
您在两个实体(Company/Employee)上选择 数据类型 List。
因此,如果您现在决定从 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);
现在的问题是:为什么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
现在是最大的结论:
如果您在Employee/Company - Entities中选择Set而不是List,就不会遇到这个问题,并且只执行一个查询!
为什么呢?因为Hibernate不再处于一个袋子的世界中(如您所知,Set不允许重复),现在可以执行仅一个查询。
因此,在涉及查询和性能的情况下,选择List和Sets之间的决定并不是那么简单!
@OrderBy
注释,但它与您的List
中的顺序无关。如果您检索带有@OrderBy
注释的实体列表,更改其顺序,合并到数据库并再次检索它,那么您更改的顺序将被保留吗?不会!您将获得通过@OrderBy
定义的相同顺序。 - Theo