Лучший способ получить одно поле только для чтения из объединенной таблицы? - PullRequest
2 голосов
/ 28 июля 2010

Часто нам требуется только одно поле только для чтения из объединенной таблицы.например, в следующем случае мне нужно только имя (клиента) из таблицы Customers. Для этого я создаю весь объект Customer, состоящий из десятков других свойств, которые мне не нужны в Orders.
Эта проблема становится более существеннойесли такое поле выбирается для дочернего класса, например, (product) имя для объекта item.Это приводит к созданию сотен или даже тысяч объектов "product" для одного заказа только для предоставления названия продукта.
Один из способов справиться с такой ситуацией может заключаться в создании дополнительного класса CustomerName только с одним свойством.Этот подход не выглядит элегантно, потому что он может создать много похожих классов для одной и той же таблицы.Может кто-нибудь предложить мне лучшее решение?

Пример отображения с обычными классами Customer и Product:

  <class name="Order" table="Orders">
    <id column="ID" name="id" type="long">
      <generator class="native" />
    </id>
    <property name="customerId" type="int" />
    <many-to-one class="Customer" name="customer" column="customerId" insert="false" update="false" fetch="join" />

    <class name="OrderItem" table="OrderItems">
      <id column="id" name="itemId" type="long">
        <generator class="native" />
      </id>
      <property name="productId" type="long" />

      <many-to-one name="order" column="orderId" not-null="true" />
      <many-to-one class="Product" name="product" column="productId" insert="false" update="false" fetch="join" />

    </class>
  </class>

Пример с дополнительными классами CustomerName и ProductName:

<class name="Order" table="Orders">
    ...
    <many-to-one class="CustomerName" name="customer" column="customerId" insert="false" update="false" fetch="join" />
    <class name="OrderItem" table="OrderItems">
      .....
      <many-to-one class="ProductName" name="product" column="productId" insert="false" update="false" fetch="join" />
    </class>
  </class> 

1 Ответ

0 голосов
/ 29 июля 2010

Если вы хотите избежать чтения слишком большого числа столбцов , у вас не так много решений:

  1. использовать проекции SQL (и, возможно, выбрать новый для безопасных результатов),
  2. используйте более легкий объект, как вы упомянули,
  3. использовать выборку ленивых свойств.

Что касается последнего варианта, я предлагаю прочитать (внимательно) соответствующий раздел документации:

19.1.7. Использование извлечения ленивых свойств

Hibernate3 поддерживает отложенную загрузку индивидуальных свойств. это методика оптимизации также известна как выборочные группы. Обратите внимание, что это это в основном маркетинговая функция; оптимизация чтения строк намного больше важнее, чем оптимизация колонки читает. Тем не менее, только загрузка некоторых свойства класса могут быть полезны в крайних случаях. Например, когда унаследованные таблицы имеют сотни столбцов и модель данных не может быть улучшена.

Чтобы включить отложенную загрузку свойств, установите ленивый атрибут вашего конкретного сопоставления свойств:

<class name="Document">
       <id name="id">
        <generator class="native"/>
    </id>
    <property name="name" not-null="true" length="50"/>
    <property name="summary" not-null="true" length="200" lazy="true"/>
    <property name="text" not-null="true" length="2000" lazy="true"/>
</class>

Загрузка ленивых свойств требует Инструментарий байт-кода времени сборки. Если ваши постоянные занятия не улучшенный, Hibernate будет игнорировать ленивый настройки свойств и вернуться к немедленная загрузка.

Для инструментов байт-кода используйте следующее задание Ant:

<target name="instrument" depends="compile">
    <taskdef name="instrument" classname="org.hibernate.tool.instrument.InstrumentTask">
        <classpath path="${jar.path}"/>
        <classpath path="${classes.dir}"/>
        <classpath refid="lib.class.path"/>
    </taskdef>

    <instrument verbose="true">
        <fileset dir="${testclasses.dir}/org/hibernate/auction/model">
            <include name="*.class"/>
        </fileset>
    </instrument>
</target>

Другой способ избежать ненужный столбец читает, по крайней мере, для транзакции только для чтения, это использовать Особенности проекции HQL или Критерии запросы. Это позволяет избежать необходимости время обработки байт-кода и является безусловно, предпочтительное решение.

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

Лично я бы предпочел первый вариант. Если это невозможно, я бы выбрал вариант № 2 (да, он вводит больше обслуживания, но вы можете держать его под контролем, если используете это решение только для частей, которые действительно являются проблемой). Я не фанат варианта № 3.

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