Проектирование объектов для Hibernate - PullRequest
0 голосов
/ 09 февраля 2010

Мне нужна помощь с проблемой дизайна. У меня возникают проблемы, когда я не могу понять, как спроектировать объект (или, может быть, несколько объектов), чтобы я мог запрашивать его так, как мне хотелось бы.

Позвольте мне начать с показа запроса sql, который возвращает именно ту информацию, которую я хочу:

select distinct rights_table.receiver_guid, user_info.name
from rights_table 
inner join user_info
on rights_table.receiver_guid = user_info.guid
where rights_table.giver_guid = '_this_is_the_argument_'

Таким образом, user_info имеет одну запись для каждого пользователя. правая_таблица содержит информацию о правах, которые giver_guid делегировал получателю. Мне все равно, какие права есть сейчас - я просто хочу иметь возможность взять giver_guid и получить список всех руководств и имен тех, на кого он дал права. У меня возникают проблемы с концептуализацией того, как преобразовать эти таблицы в объектную модель таким образом, чтобы я мог выполнить этот запрос.

Если это помогает узнать, receive_guid и giver_guid оба (могут быть оба) сопоставления «многие к одному» с user_info.guid. user_info.guid - это ПК для этой таблицы; pk на rights_table - это еще один столбец, не упомянутый здесь.

Редактировать: Мое решение:

Как предложил Тим, я поместил сопоставления "многие к одному" в таблицу объектов "объект", которая связывала таблицу прав с таблицей пользователей. Мне потребовалось некоторое время, чтобы понять, что Hibernate объединяет для вас простоту, когда вы выполняете такие сопоставления, поэтому вот что я в основном закончил для HQL:

String hqlQuery =           
    "select right.recipient_guid, user.name " +
    "from rightsTable right, userInfo user " +
    "where right.recipient_guid = user.guid and right.giver_guid like :giver_guid";

Честно говоря, я даже не знаю, происходят ли там закулисные объединения, но я знаю, что это дает мне информацию, которую я изначально хотел. Если у кого-то есть предложения по более эффективному выполнению этого запроса, сообщите мне.

Ответы [ 2 ]

1 голос
/ 10 февраля 2010

Попытка отобразить запросы и таблицы на объекты трудна, потому что концептуальные модели сильно отличаются. Отложив ваш оператор SQL и просто работая с данными, которые вы хотите экстраполировать, я получаю следующие объекты:

  • Пользователь
    (id, name, Set< RightsAssignment> rights_given, Set< RightsAssignment> rights_recieved, info, ...)
  • правый
    (id, name, level, Set< RightsAssignment> assignments, info, ...)
  • RightsAssingment
    (id, giver_id, reciever_id, right_id, date, info...)

Таким образом, RightsAssignment (простите имя, измените его на что-то подходящее) - это присвоение права пользователем другому пользователю с необязательной дополнительной информацией, такой как поле assignment.date выше (оно может вам и не понадобиться сейчас, но это делает ваши модели более расширяемыми).
Поля в RightsAssignment будут иметь значение ManyToOne для дающего, получателя и права, где для пользователя и права будет OneToMany, сопоставленное с полями в RightsAssignment.

Чтобы получить список прав, назначенных каким-либо одним пользователем, вам просто нужно запросить в таблице RightsAssignment записи, в которых giver_id совпадает с user.id.

Надеюсь, это поможет!

1 голос
/ 09 февраля 2010

Если это поможет узнать, receive_guid и giver_guid оба (могут быть оба) сопоставления "многие к одному" user_info.guid. user_info.guid является рк на этом столе; ПК на rights_table - это еще один столбец, упоминается здесь.

Я бы попробовал следующее:

  • Пользователь имеет отношение «один ко многим» «rightsGiven» с нужным объектом.
  • У пользователя есть отношение один-ко-многим «rightsReceived» к нужному объекту.
  • Право имеет отношение "данный к одному" для пользователя.
  • Право имеет отношение "данный к одному" для пользователя.

Чтобы получить список пользователей, которые получили некоторые права от пользователя X, тогда

  • пользователь загрузки X
  • Пройдите через сборник "RightstGiven" из прав
  • за каждое право получит «данное пользователю»

После того, как вы загрузили объект, когда вы пройдете по графику, hibernate лениво загрузит объект для вас. Это может привести к тому, что многие запросы выполняются в режиме hibernate, особенно проблема Select N + 1 . Используйте затем нетерпеливую выборку, чтобы hibernate использовал затем соединение. Например. @OneToMany(fetch = FetchType.EAGER). Установите нетерпеливую выборку на "rightsGiven" и "GivenTo".

Затем вы можете контролировать так называемую максимальную глубину выборки , чтобы гарантировать, что hibernate не будет загружать график весь с нетерпением. В этом случае у нас есть 2 отношения, которые нужно выбрать с нетерпением (rightsGiven + GivenTo), поэтому установите его равным 2. Это должно привести к запросу с двумя внешними соединениями.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...