Pergunta

consideram tabela

sales (id, seller_id, amount, date)

e aqui é uma visão que é gerada a partir sales usando consulta SELECT seller_id, SUM(amount) FROM sales GROUP BY seller_id

total_sales (seller_id, amount)

Eu quero fazer uma entidade para as vendas totais, mas sem a vista no lado sql.

Esta entidade será construído a partir de uma consulta. A coisa mais próxima que eu encontrei é este , mas eu não poderia fazê-lo funcionar.

Mesmo se eu definir o carregador, hibernate olhares para a mesa da entidade e dá um erro se não puder encontrá-lo. Se eu criar a tabela não carrega a entidade a partir da consulta chamado I definido, Hibernate gera a consulta em si.

Existe uma maneira de fazer @Loader ao trabalho ou há outra maneira que eu possa mapear uma consulta para entidade?

Foi útil?

Solução

Por que você não apenas usar new na consulta?

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

Você só escrever uma TotalSales classe com um construtor que tomam a seller_id e um inteiro.


Editar : Ao usar critérios API, você pode usar o AliasToBeanResultTransformer (Veja documentação da API ). Ele copia todos os nome de alias para uma propriedade com o mesmo nome.

 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();

Em seguida, seu TotalSales precisa de uma propriedade SellerId e Count.

Outras dicas

Além de resposta de Stefan, você também pode usar um HQL explícita consulta para

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

O resultado é naturalmente armazenado em List. Se este tipo de dados não é conveniente para você, você pode:

  • criar novos objetos TotalSale com eles (resposta uso de Stefan seria melhor provavelmente)
  • Crie um mapa para armazenar os dados (você também pode incorporar este diretamente no pedido).

Você pode tentar definir um carregador personalizado. Eu nunca usei isso, mas parece ser razoável:

<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>

Não tenho certeza se o filtro no seller_id é necessário.

Você referenciar esta consulta nomeada em um mapeamento de classe:

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

mais detalhes em o manual .

Como alternativa, você pode usar diretamente uma consulta de nome a partir do código, desta forma você não precisa de um mapeamento de TotalSale e não tem que escrever a consulta no código. consultas nomeadas também pode retornar objetos. Veja detalhes sobre o nome consultas na documentação.

Se você realmente quer uma entidade específica apenas para este trabalho que você pode usar uma 'fórmula' em uma propriedade personalizada

<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;}
}

, como tal, a sua acessível para o motor Critérios para a ordem-by de, restrições etc., que eu acho que é a razão que você quer usá-lo.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top