Hibernate:@OrderBy vs @OrderColumn维护集合的顺序

Pha*_*mar 14 hibernate

在保持持久性以及从数据库检索时维护集合顺序的首选方法是什么?

我知道@OrderBy更多的是内存中的排序,只有当你按照你选择的列的顺序预先排序时才可以检索.

假设我选择使用由数据库序列支持的列,hibernate将确保集合中的元素以与集合(例如List)相同的顺序保持.

任何想法?

更多细节:

假设我有一个与B类有一对多关系的A类.B有一个主键字段'Id',它由DB中的序列支持.

Class A {
  List<B> bList;
}
Run Code Online (Sandbox Code Playgroud)

我一直想保留A中元素B的顺序,如下所示:

bList = { b1, b2, b3 }
Run Code Online (Sandbox Code Playgroud)

实现的一种方法是使用@OrderBy("Id ASC").只有当列表B按顺序保存在下面时,这才有效:

----------------
Id ----bValue
----------------

1------ b1
2------ b2
3-------b3
------------------
Run Code Online (Sandbox Code Playgroud)

当我们检索,因为它按Id排序,维持订单.

让我们通过以下方式保存集合B:

----------------
Id ----bValue
----------------
1------ b2
2------ b1
3-------b3
------------------
Run Code Online (Sandbox Code Playgroud)

当我们检索时,列表B的顺序进行折腾(因为它是按Id列的顺序).所以我的问题是,如果集合B始终保持与列表中显示的顺序相同或不相同.

JB *_*zet 25

OrderBy将order by子句添加到生成的SQL中,以按目标实体的表的列对所检索集合的成员进行排序:

@OrderBy("lastname ASC")
public List<Student> students;
Run Code Online (Sandbox Code Playgroud)

将生成一个SQL查询,如

select ... order by student.lastname ASC
Run Code Online (Sandbox Code Playgroud)

OrderColumn定义表中附加列的名称,包含列表中实体的索引.如果更改列表中元素的顺序,Hibernate将更改此列的值.如果您的学生在此列中有0,3和5作为值,则列表将为

[student0, null, null, student3, null, student5]
Run Code Online (Sandbox Code Playgroud)

在这两个注释的javadoc中对此进行了详细描述.

编辑:

分配B标识符的顺序取决于您如何持久保存这些B实例:

  • 如果你明确地调用session.save()session.saveOrUpdate(),这会为实体分配一个ID,所以为b1,b2和b3调用它会尊重命令
  • AFAIK,所有其他方法(cascading,merge(),persist())不保证任何订单(除非您合并或持久,然后flush())

因此,如果您希望列表按此顺序保存b1,b2和b3,无论这些方式如何保留,最好的办法是@OrderColumn在集合中添加注释.Hibernate将自动填充此列,其中0表示b1,1表示b2,2表示b3.当你重新加载父实体时,它们将在列表中的顺序相同.