Domanda

considera la tabella

sales (id, seller_id, amount, date)

e qui è una vista che viene generata da sales utilizzando la query SELECT seller_id, SUM (importo) DA sales GROUP BY seller_id

total_sales (seller_id, amount)

Voglio creare un'entità per le vendite totali ma senza la vista sul lato sql.

Questa entità sarà costruita da una query. La cosa più vicina che ho trovato è this , ma non sono riuscito a farlo funzionare.

Anche se definisco il caricatore, l'ibernazione cerca la tabella dell'entità e genera un errore se non riesce a trovarlo. Se creo la tabella, non carica l'entità dalla query denominata che ho definito, Hibernate genera la query stessa.

C'è un modo per far funzionare @Loader o c'è un altro modo in cui posso mappare una query sull'entità?

È stato utile?

Soluzione

Perché non usi semplicemente new nella query?

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

Devi solo scrivere una classe TotalSales con un costruttore che prende il seller_id e un numero intero.


Modifica : quando si utilizza l'API dei criteri, è possibile utilizzare AliasToBeanResultTransformer (vedere documenti API ). Copia ogni nome di alias in una proprietà con lo stesso 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();

Quindi il tuo TotalSales ha bisogno di una proprietà SellerId e Count .

Altri suggerimenti

Oltre alla risposta di Stefan, puoi anche utilizzare una query HQL esplicita per

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

Il risultato è naturalmente archiviato in Elenco. Se questo tipo di dati non è conveniente per te, potresti:

  • crea nuovi oggetti TotalSale con loro (usa probabilmente la risposta di Stefan sarebbe meglio)
  • crea una mappa per archiviare i dati (puoi anche incorporarlo direttamente nella richiesta).

Puoi provare a definire un caricatore personalizzato. Non l'ho mai usato, ma sembra ragionevole:

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

Non sono sicuro se è necessario il filtro su seller_id.

Fai riferimento a questa query denominata in un mapping di classe:

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

Ci sono maggiori dettagli in il manuale .

In alternativa, è possibile utilizzare direttamente una query del nome dal codice, in questo modo non è necessario un mapping di TotalSale e non è necessario scrivere la query nel codice. Le query con nome possono anche restituire oggetti. Vedi dettagli sulle query con nome nella documentazione.

se vuoi davvero un'entità specifica solo per questo lavoro puoi usare una "formula" su una proprietà personalizzata

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

in quanto tale è accessibile al motore dei criteri per ordini, restrizioni ecc. che ritengo sia il motivo per cui si desidera utilizzarlo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top