Сохранение упорядоченных доменных объектов - PullRequest
1 голос
/ 16 февраля 2011

Очень распространенный вариант использования во многих веб-приложениях заключается в том, что объекты домена могут быть заказаны пользователем в веб-интерфейсе, и этот порядок сохраняется для дальнейшего использования; но я заметил, что каждый раз, когда мне нужно реализовать это, я всегда заканчиваю тем, что придумал решение, которое отличается от других и добавляет значительный вес и сложность простому объекту домена. В качестве примера предположим, что у меня есть постоянная сущность Person

Person {
   long id
   String name
}

Пользователь переходит на /myapp/persons и видит всех людей в системе в том порядке, в котором они получают компенсацию (или что-то еще) - все люди могут быть нажаты, перетащены и сброшены в другое положение - при загрузке страницы опять заказ запоминается. Проблема в том, что реляционные базы данных, похоже, не имеют хорошего способа сделать это; ни ORMs (спящий режим - это то, что я использую)

Я думал о общей методологии упорядочения - но будут некоторые издержки, так как данные будут сохраняться отдельно, что может замедлить доступ в некоторых случаях использования. У меня вопрос: кто-нибудь придумал действительно хороший способ смоделировать порядок постоянных доменных объектов?

Я работаю в JavaEE с Hibernate или JDBCTemplate - поэтому любые примеры кода будут наиболее полезны с этими технологиями в качестве их основы. Или любые концептуальные идеи тоже приветствуются.

ОБНОВЛЕНИЕ: Я не уверен, где я ошибся, но мне кажется, что я был неясен, так как большинство ответили ответами, которые действительно не соответствуют моему вопросу (как это происходит в моей голове). Проблема не в том, как упорядочить строки или столбцы при их извлечении, а в том, что порядок объектов домена изменяется - кто-то щелкает и перетаскивает «человека» из нижней части списка в верхнюю часть списка - они обновляют страница и список теперь в указанном порядке.

Ответы [ 5 ]

1 голос
/ 16 февраля 2011

Одно возможное универсальное решение:

Создайте таблицу для сохранения информации сортировки, простейшим случаем будет одно сортируемое поле на объект с направлением:

table 'sorts'
* id: PK
* entity: String
* field: String
* direction: ASC/DESC enumeration (or ascending boolean flag)

Можно сделать большеусложняется добавлением userId для сортировки по каждому пользователю или добавлением таблицы sort_items с внешним ключом для поддержки сортировки по нескольким полям одновременно.

Как только вы сохраняете информацию сортировки, это очень простодобавление экземпляров Order к критериям (если это то, что вы используете) или объединение порядка по операторам в HQL.

Это также освобождает ваши сущности от обычной и порядковой информации, которая в данном случае звучит как правильнаяподход, так как упорядочение предназначено исключительно для взаимодействия с пользователем.

Обновление - постоянный порядок сущностей Учитывая тот факт, что вы хотите иметь возможность переупорядочивать сущности, а не просто определять для них сортировку, тогдавам действительно нужно сделать порядковое или индексное значение частью определения сущности.

Проблема, как я уверен, вы понимаете, состоит в том, что количество сущностей, которые необходимо обновить, в худшем случае перемещает последнюю сущность в верхнюю часть списка.

Выможно использовать значение приращения, отличное от 1 (скажем, 10), поэтому у вас будет:

ordinal | name
10      | Crosby
20      | Stills
30      | Nash
40      | Young

В большинстве случаев обновление строки потребует выбора двух элементов и обновления одного.Если я хочу переместить Янга в позицию 2, я выбираю текущий элемент 2 и предыдущий элемент из базы данных, чтобы получить порядковые номера 10 и 20. Используйте их для создания нового порядкового номера ((20 - 10) / 2 + 10 = 15),Теперь выполните одно обновление Янга с порядковым номером 15.

Если вы дойдете до точки, где деление на два дает тот же индекс, что и у одной из только что загруженных вами сущностей, это означает, что пришло время порождать задачунормализовать порядковые значения в соответствии с вашим первоначальным приращением.

1 голос
/ 16 февраля 2011

Проблема в том, что реляционные базы данных просто не имеют хорошего способа сделать это;и ORMs (hibernate - это то, что я использую)

Я не уверен, откуда у вас такое впечатление. Hibernate специально поддерживает отображение индексированных коллекций (который является «списком» под другим именем), что обычно сводится к хранению столбца «list-index» в таблице, содержащей коллекцию элементов.

Пример, взятый непосредственно из руководства:

<list name="carComponents"
    table="CarComponents">
    <key column="carId"/>
    <list-index column="sortOrder"/>
    <composite-element class="CarComponent">
        <property name="price"/>
        <property name="type"/>
        <property name="serialNumber" column="serialNum"/>
    </composite-element>
</list>

Это позволит связать List<CarComponents> с вашей корневой сущностью, хранящейся в таблице CarComponents со столбцом sortOrder.

1 голос
/ 16 февраля 2011

При получении результатов просто создайте запросы HQL с другим предложением ORDER BY, в зависимости от того, что пользователь использовал в последний раз

0 голосов
/ 16 февраля 2011

Я думаю, что реляционные базы данных не могут работать лучше, чем выделенный столбец порядка.

Идея «порядка» на самом деле не определена в SQL для чего-либо, кроме курсоров, и они не являются основной концепцией отношений, а скорее деталями реализации.

Для всех, кого я знаю, единственное, что нужно сделать, это абстрагировать столбец порядка с помощью @OrderColumn (JPA2, поэтому совместим с Hibernate 3.5+).

0 голосов
/ 16 февраля 2011

Насколько я знаю, JPA 2.0 обеспечивает поддержку упорядоченных списков: https://secure.wikimedia.org/wikibooks/en/wiki/Java_Persistence/Relationships#Order_Column_.28JPA_2.0.29

...