Карта объекта с помощью запроса в Hibernate - PullRequest
6 голосов
/ 11 сентября 2009

рассмотрим таблицу

sales (id, seller_id, amount, date)

и вот представление, сгенерированное из sales с использованием запроса SELECT seller_id, SUM(amount) FROM sales GROUP BY seller_id

total_sales (seller_id, amount)

Я хочу создать объект для общих продаж, но без представления о стороне sql.

Эта сущность будет построена из запроса. Самое близкое, что я нашел, это это , но я не мог заставить его работать.

Даже если я определю загрузчик, hibernate ищет таблицу сущности и выдает ошибку, если не может ее найти. Если я создаю таблицу, она не загружает объект из именованного запроса, который я определил, Hibernate генерирует сам запрос.

Есть ли способ заставить @Loader работать или есть другой способ сопоставить запрос с сущностью?

Ответы [ 4 ]

18 голосов
/ 11 сентября 2009

Почему бы вам просто не использовать new в запросе?

select new TotalSales(seller_id, count(seller_id))
from sales
group by seller_id

Вы просто пишете класс TotalSales с конструктором, принимающим seller_id и целое число.


Редактировать : при использовании API критериев вы можете использовать AliasToBeanResultTransformer (см. Документы API ). Он копирует каждое псевдоним в одноименное свойство.

 List list = s.createCriteria(Sales.class)
  .setProjection(Projections.projectionList()
    .add( Projections.property("id"), "SellerId" )
    .add( Projections.rowCount("id"), "Count" ) )
  .setResultTransformer( 
    new AliasToBeanResultTransformer(TotalSales.class) )
  .list();

Тогда вашему TotalSales требуется свойство SellerId и Count.

0 голосов
/ 18 сентября 2009

если вы действительно хотите конкретную сущность только для этой работы, вы можете использовать «формулу» для пользовательского свойства

<class name="SellerSales" table="Sales" lazy="true">
    <id name="SellerId" column="SellerId" type="int">
        <generator class="native" />
    </id>
    <property name="SalesSum" type="float" update="false" insert="false" 
            formula="select SUM(sal.ammount) from sales sal where sal.seller_id = SellerId)" />
</class>

public class SellerSales
{
    public int SellerId {get; set;}
    public float SalesSum {get; set;}
}

как таковой, он доступен для механизма Criteria для упорядочивания, ограничений и т. Д., По-моему, и является причиной, по которой вы хотите его использовать.

0 голосов
/ 18 сентября 2009

Вы можете попытаться определить настроенный загрузчик. Я никогда не использовал это, но это кажется разумным:

<sql-query name="totalSale">
    <return alias="ts" class="TotalSale" />
    SELECT seller_id as {ts.seller_id}, SUM(amount) as ts.amount 
    FROM sales 
    WHERE seller_id = ?
    GROUP BY seller_id
</sql-query>

Не уверен, нужен ли фильтр для seller_id.

Вы ссылаетесь на этот именованный запрос в отображении класса:

<class name="TotalSale">
    <id name="seller_id">
        <generator class="increment"/>
    </id>
    <property name="seller_id" />
    <property name="amount" />
    <loader query-ref="totalSale"/>
</class>

В руководстве больше подробностей .

В качестве альтернативы, вы можете напрямую использовать запрос имени из кода, таким образом вам не нужно отображать TotalSale и не нужно писать запрос в коде. Именованные запросы также могут возвращать объекты. См. подробности об именованных запросах в документации.

0 голосов
/ 11 сентября 2009

В дополнение к ответу Стефана вы также можете использовать явный HQL-запрос к

    SELECT seller_id, SUM(amount) FROM sales GROUP BY seller_id

Результат естественно сохраняется в списке. Если этот тип данных вам не подходит, Вы могли бы:

  • создавать новые объекты TotalSale с ними (лучше использовать ответ Стефана)
  • создать карту для хранения данных (вы также можете встроить это непосредственно в запрос).
...