15

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

我知道 @OrderBy 更像是一种内存排序,只有当您按照您选择的列的顺序保留行时,它才可能在检索时起作用。

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

任何想法?

更多细节:

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

Class A {
  List<B> bList;
}

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

bList = { b1, b2, b3 }

一种实现方法是使用@OrderBy(“Id ASC”)。仅当列表 B 按以下顺序保留时,这才有效:

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

1------ b1
2------ b2
3-------b3
------------------

当我们检索时,因为它是按 Id 排序的,所以顺序保持不变。

假设集合 B 以下列方式持久化:

----------------
Id ----bValue
----------------
1------ b2
2------ b1
3-------b3
------------------

当我们检索时,列表 B 的顺序进行了折腾(因为它是按 Id 列排序)。所以我的问题是,如果集合 B 始终以与列表中出现的顺序相同的顺序持续存在。

4

1 回答 1

31

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

@OrderBy("lastname ASC")
public List<Student> students;

将生成一个 SQL 查询,如

select ... order by student.lastname ASC

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

[student0, null, null, student3, null, student5]

这在这两个注释的 javadoc中有很好的描述。

编辑:

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

  • 如果您明确调用session.save(), of session.saveOrUpdate(),这将为实体分配一个 ID,因此为 b1、b2 和 b3 调用它将遵守顺序
  • AFAIK,所有其他方法(级联、合并()、持久化())不保证任何顺序(除非你合并或持久化,然后flush()

因此,如果您希望列表按此顺序保存 b1、b2 和 b3,而不管它们的持久化方式如何,最好的办法是向@OrderColumn集合添加注释。Hibernate 将自动填充此列,其中 b1 为 0,b2 为 1,b3 为 2。当您重新加载父实体时,它们在列表中的顺序相同。

于 2012-07-11T13:09:22.997 回答