[N] Hibernate: свойства извлечения, связанные с просмотром связанного класса - PullRequest
0 голосов
/ 09 июня 2010

(чувствовал себя совершенно беспомощным в формулировании подходящего заголовка ...)

Можно ли определить отображение для класса таким образом, что некоторые свойства извлекаются из другой таблицыс помощью запроса на соединение?

В моем приложении на C # я отображаю список объектов "A", а также некоторые свойства связанных с ними объектов "B" и свойства связанных с ними объектов "C" B:

A.Name    B.Name    B.SomeValue    C.Name
Foo       Bar       123            HelloWorld
Bar       Hello     432            World
...

Чтобы уточнить: A имеет FK-B, B-FK-C (например, BankAccount -> Person -> Company).

Если я расширяю класс Aпо свойствам "BName", "BSomeValue" и "CName" можно ли заставить [N] Hibernate выдавать запрос типа

select A.Name, B.Name as BName, B.SomeValue as BSomeValue, C.Name as CName
from A
join B on A.B_ID = B.ID
join C on B.C_ID = C.ID

и отображать все результаты этого запроса в свойства A?


Справочная информация:

Я пробовал два подхода для загрузки этих свойств из базы данных (используя NHibernate): быстрый подход и чистый подход.Мой возможный вопрос - как сделать быстрый и чистый заход на посадку.

Быстрый заход на посадку:

  • Определитьпредставление в базе данных, которое объединяет A, B, C и предоставляет все эти поля.
  • В классе A определите свойства "BName", "BSomeValue", "CName"
  • Define aотображение спящего режима между A и представлением, тогда как необходимые свойства B и C сопоставляются с update="false" insert="false" и на самом деле основаны на таблицах B и C, но Hibernate не знает об этом, поскольку использует представление.

Таким образом, листинг загружает только один объект на запись «А», что довольно быстро.Если код пытается получить доступ к фактическому связанному свойству, «AB», я запускаю другой HQL-запрос для получения B, устанавливаю свойство и обновляю также поддельные свойства BName и BSomeValue.

Чистый подход:

  • Нет представления.
  • Класс A отображается в таблицу A, B в B, C в C.
  • При загрузке спискаA, я делаю двойное левое соединение, чтобы получить B и C: from A a left join fetch a.B left join fetch a.B.C
  • B.Name, B.SomeValue и C.Name доступны через загруженные ассоциации.

Недостаток этого подхода заключается в том, что он работает медленнее и занимает больше памяти, поскольку ему необходимо создать и отобразить 3 объекта для каждой записи «A»: каждый объект A, B и C.

Быстрый и чистый подход:

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

  • Не иметь представлений в базе данных.
  • Объявить свойства "BName", "BSomeValue", "CName" в классе "A".
  • Определите сопоставление для A так, чтобы NHibernate извлекал A и эти свойства вместе, используя SQL-запрос соединения в качестве представления базы данных.
  • Сопоставление должно по-прежнему позволять определять ленивый многоодна ассоциация для получения ABC

Мои вопросы:

  • Возможно ли это?
  • Это [не] хитро?
  • есть лучший способ?

1 Ответ

1 голос
/ 09 июня 2010

Ваш "чистый" подход наиболее близок к тому, каким он должен быть (другие даже не стоит пытаться)

Прежде чем идти по пути join fetch, вы должны увидеть, что происходит без Это.В зависимости от использования, вы можете найти, что это достаточно хорошо.

Вы также можете прочитать о пакетном размере и кэшировании в документации.

И, прежде всего, вы не должны пытаться микрооптимизировать, прежде чем обнаружите реальные проблемы.Когда вы говорите «Недостаток этого подхода в том, что он работает медленнее и занимает больше памяти» , я не думаю, что вы на самом деле его измерили.

...