Question

considérer le tableau

sales (id, seller_id, amount, date)

et voici une vue générée à partir de ventes à l'aide de la requête SELECT vendeur_id, SUM (montant) FROM ventes GROUP BY vendeur_id

total_sales (seller_id, amount)

Je souhaite créer une entité représentant le total des ventes, mais sans la vue du côté SQL.

Cette entité sera construite à partir d'une requête. La chose la plus proche que j'ai trouvée est la cette , mais je ne pouvais pas le faire fonctionner.

Même si je définis le chargeur, hibernate recherche la table de l'entité et génère une erreur s'il ne la trouve pas. Si je crée la table, elle ne charge pas l'entité à partir de la requête nommée que j'ai définie, Hibernate génère la requête elle-même.

Existe-t-il un moyen de faire fonctionner @Loader ou existe-t-il un autre moyen de mapper une requête à une entité?

Était-ce utile?

La solution

Pourquoi n'utilisez-vous pas simplement le nouveau dans la requête?

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

Vous venez d'écrire une classe TotalSales avec un constructeur prenant le vendeur_id et un entier.

Modifier : lorsque vous utilisez l'API de critères, vous pouvez utiliser AliasToBeanResultTransformer (voir Documents de l'API ). Il copie chaque nom d'alias dans une propriété du même nom.

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

Ensuite, votre TotalSales a besoin d'une propriété SellerId et Nombre .

Autres conseils

En plus de la réponse de Stefan, vous pouvez également utiliser une requête HQL explicite pour

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

Le résultat est naturellement stocké dans la liste. Si ce type de données ne vous convient pas, vous pourriez:

  • créer de nouveaux objets TotalSale avec eux (utiliser la réponse de Stefan serait probablement préférable)
  • créez une carte pour stocker les données (vous pouvez également l'intégrer directement dans la demande).

Vous pouvez essayer de définir un chargeur personnalisé. Je n'ai jamais utilisé cela, mais cela semble raisonnable:

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

Je ne sais pas si le filtre sur le vendeur_id est nécessaire.

Vous référencez cette requête nommée dans un mappage 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>

Il existe plus de détails dans le manuel .

Vous pouvez également utiliser directement une requête de nom à partir du code. Ainsi, vous n'avez pas besoin de mapper TotalSale et vous n'avez pas à écrire la requête dans le code. Les requêtes nommées peuvent également renvoyer des objets. Voir des détails sur les requêtes nommées dans la documentation.

si vous voulez vraiment une entité spécifique uniquement pour ce travail, vous pouvez utiliser une "formule" sur une propriété personnalisée

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

en tant que tel, il est accessible au moteur de critères pour les commandes, les restrictions, etc., ce qui, à mon avis, est la raison pour laquelle vous souhaitez l'utiliser.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top