Спящий режим: @OrderBy vs @OrderColumn для поддержания порядка сбора
Каков предпочтительный способ поддержания порядка коллекции при сохранении, а также при извлечении из базы данных?
Я знаю, что @OrderBy больше относится к сортировке в памяти, которая может работать при извлечении только тогда, когда вы задаете строки в порядке расположения столбца, который вы выбрали.
Предположим, что я решил использовать столбец, поддерживаемый последовательностью базы данных, будет спящий режим, чтобы элементы в коллекции сохранялись в том же порядке, что и в коллекции (например, List).
Любая мысль?
Подробнее:
Допустим, у меня есть класс A, который имеет отношения "один ко многим" с классом B. В поле первичного ключа "Id", который поддерживается последовательностью в БД.
Class A {
List<B> bList;
}
Я всегда хотел сохранить порядок элементов B в A, как показано ниже:
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 идет для броска (поскольку это порядок по столбцу Идентификатор). Поэтому мой вопрос, если коллекция B всегда сохраняется в том же порядке, что и в списке, или нет.
Ответы
Ответ 1
OrderBy добавляет предложение order by к сгенерированному SQL для упорядочения членов извлеченной коллекции по столбцу таблицы целевого объекта:
@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 этих двух аннотаций.
EDIT:
Порядок, в котором назначены B-идентификаторы, зависит от того, как вы сохраняете эти экземпляры B:
- если вы явно вызываете
session.save()
, из session.saveOrUpdate()
, это присваивает идентификатор сущности, поэтому вызов его для b1, b2 и b3 будет уважать порядок
- AFAIK, все остальные методы (cascading, merge(), persist()) не гарантируют никакого порядка (кроме случаев, когда вы сливаетесь или сохраняетесь, а затем
flush()
)
Итак, если вы хотите, чтобы список держал b1, b2 и b3 в этом порядке, независимо от того, как они сохраняются, лучше всего добавить в коллекцию аннотацию @OrderColumn
. Hibernate автоматически заполнит этот столбец 0 для b1, 1 для b2 и 2 для b3. И когда вы перезагрузите родительский объект, они будут в том же порядке в списке.