2010-01-14 8 views
28

J'essaie d'obtenir un rapport en utilisant Criteria et ProjectionList, et je suis assez nouveau en utilisant hibernate. J'ai donc ce modèle:Regrouper par mois avec des critères dans Hibernate

private Long _userId; 

private Category _category; 

private Long _companyId; 

private Double _amount; 

private Date _date; 

Et je crée la requête en utilisant ceci:

public List sumPaymentsByUserCategoryPeriod(Category category, Long userId,Integer period){ 
    GregorianCalendar from = new GregorianCalendar(); 
    from.add(Calendar.MONTH, -period); 
    List<CategoryAmount> resultDTO= new ArrayList<CategoryAmount>(); 

    Criteria criteria = getSession().createCriteria(Payment.class); 
    criteria.add(Restrictions.eq("_category", category)); 
    criteria.add(Restrictions.eq("_userId",userId)); 
    criteria.add(Restrictions.between("_date", from.getTime(), new Date())); 

    ProjectionList projectionList = Projections.projectionList(); 
    projectionList.add(Projections.sum("_amount")); 
    projectionList.add(Projections.groupProperty("_date")); 
    criteria.setProjection(projectionList); 
    return criteria.list(); 

} 

Fondamentalement, cette méthode receive une catégorie et un userId pour filtrer les enregistrements des paiements et une période, qui indiquera combien de mois à partir de maintenant à l'arrière, je veux résumer. Comment puis-je regrouper les résultats de la somme par mois?

Une aide ou un conseil j'apprécierais!

Répondre

37

J'ai trouvé la réponse, et c'est assez simple. J'ai changé le "groupProperty" dans les critères de ProjectionList pour cela:

projectionList.add(Projections.sqlGroupProjection(
    "month({alias}.DATE) as month, year({alias}.DATE) as year", 
    "month({alias}.DATE), year({alias}.DATE)", 
    new String[]{"month","year"}, 
    new Type[] {Hibernate.DOUBLE})); 

D'accord. Je vais vous expliquer le sqlGroupProjection. Le premier argument est la partie de la requête après de « sélectionner », par exemple:

Select [firstPartOfSqlGroupProjection] * boo; 

Le « {alias} » est l'alias qui hiberne utilisation dans la requête pour faire référence à une table.

Le deuxième argument de la fonction sqlGroupProjection est le groupe par critère, le troisième argument est les noms de colonnes que vous obtiendrez du groupe et enfin, le type de données que vous utiliserez.

+3

Comment gérer différents DB? tels que MSSQL et Oracle? comme Oracle utilise to_char et mssql utilisent weeknum ... – zolibra

0

Vous pouvez utiliser un SQLQuery en veille prolongée, voici un exemple:

public List<MonthlyPoint> groupByMonth(ChartRequest request){ 

    SQLQuery query = getSession().createSQLQuery("SELECT \n" + 
     "sum(this_.amount) as amount, \n" + 
     "extract(month from this_.fecha) as month, \n" + 
     "extract(year from this_.fecha) as year\n" + 
     "FROM jornada this_ \n" + 
     "GROUP BY \n" + 
     "month, \n" + 
     "year \n" + 
     "ORDER BY \n" + 
     "year asc, \n" + 
     "month asc"); 

     query.setResultTransformer(Transformers.aliasToBean(MonthlyPoint.class)); 
     return query.list(); 
} 


public class MonthlyPoint { 
    private Double year; 
    private Double month; 
    private Double amount; 
    //-- getters and setters here -- 
}