簡體   English   中英

如何使用SUM和GROUP BY JPA Java創建條件查詢

[英]How to Create a Criteria Query with SUM and GROUP BY JPA Java

這里我的更改基於Ish答案:

public List<TopUpRAMSInfo> listadoTOPUP2(Date fechaI, Date fechaF) {
        List<TopUpRAMSInfo> lista;
        CriteriaQuery<TopUpRAMSInfo> data = cb.createQuery(TopUpRAMSInfo.class);
        Root<TopUpRAMS> c = data.from(TopUpRAMS.class);
        data.select(cb.construct(TopUpRAMSInfo.class,
                c.get("deviceId"),
                cb.sum(c.get("rechargeValue"))
        )
        );
        data.where(cb.greaterThanOrEqualTo(c.get("connectionTime"), fechaI),
                cb.lessThanOrEqualTo(c.get("connectionTime"), fechaF)
        );
        data.groupBy(c.get("deviceId"));
        TypedQuery<TopUpRAMSInfo> datos = emDAO.createQuery(data);
        lista = datos.getResultList();
        return lista;
    }

現在我有這個錯誤:java.lang.IllegalArgumentException:在類上發生異常:使用選擇條件類型作為參數的構造函數的類ENTITY.TopUpRAMSInfo。 如果此CriteriaQuery不是構造函數查詢,請驗證選擇是否與返回類型匹配。

-----原始帖子-----

我有一些問題這樣做。 這是我正在嘗試構建的第一個真正的程序,我需要根據另一個來總結一個字段。

這是我到目前為止的代碼(請注意, TopUpRAMS是我的實體, emDAO是我的實體經理。

public List<TopUpRAMS> listadoTOPUP2(Date fechaI, Date fechaF) {
    List<TopUpRAMS> lista;

    CriteriaQuery<TopUpRAMS> data = cb.createQuery(TopUpRAMS.class);
    Root<TopUpRAMS> c = data.from(TopUpRAMS.class);

    data.multiselect(c.get("deviceId"), cb.sum(c.get("rechargeValue")));
    data.where(cb.greaterThanOrEqualTo(c.get("connectionTime"), fechaI));
    cb.and(cb.lessThanOrEqualTo(c.get("connectionTime"), fechaF));
    data.groupBy(c.get("deviceId"));

    TypedQuery<TopUpRAMS> datos = emDAO.createQuery(data);
    lista = datos.getResultList();
    return lista;
}

如何構造CriteriaQuery的WHERE部分存在問題。 此表達式是唯一添加到WHERE子句的表達式:

cb.greaterThanOrEqualTo(c.get("connectionTime"), fechaI)

但不是這個:

cb.lessThanOrEqualTo(c.get("connectionTime"), fechaF)

任何ff。 可以解決這個問題

  1. 使用cb.and():

     data.where(cb.and( cb.greaterThanOrEqualTo(c.get("connectionTime"), fechaI), cb.lessThanOrEqualTo(c.get("connectionTime"), fechaF) ) ); 
  2. CriteriaQuery.where()可以接受可變數量的Expression類型的參數,它們將使用連接(AND運算符)進行組合。 所以,我們不需要使用cb.and():

     data.where(cb.greaterThanOrEqualTo(c.get("connectionTime"), fechaI), cb.lessThanOrEqualTo(c.get("connectionTime"), fechaF) ); 

CriteriaQuery中使用的類型也存在問題。 您通過2個字段的data.multiselect()進行投影,這將無法轉換為TopUpRams實體。

有多種方法可以進行多選/投影:

  1. CriteriaQuery類型將是Object []

     CriteriaQuery<Object[]> data = cb.createQuery(Object[].class); Root<TopUpRAMS> c = data.from(TopUpRAMS.class); data.multiselect(c.get("deviceId"), cb.sum(c.get("rechargeValue"))); 
  2. CriteriaQuery類型將是Tuple

     CriteriaQuery<Tuple> data = cb.createTupleQuery(); Root<TopUpRAMS> c = data.from(TopUpRAMS.class); data.multiselect(c.get("deviceId"), cb.sum(c.get("rechargeValue"))); 
  3. 使用構造函數

     CriteriaQuery<TopUpRAMSInfo> data = cb.createQuery(TopUpRAMSInfo.class); Root<TopUpRAMS> c = data.from(TopUpRAMS.class); data.select(cb.construct(TopUpRAMSInfo.class, c.get("deviceId"), cb.sum(c.get("rechargeValue")) ) ); 

    為此,您需要創建一個單獨的類來表示查詢結果的類型(它不必是實體):

     public class TopUpRAMSInfo { private Long deviceId; private Double sumRechargeValue; public TopUpRAMSInfo(Long deviceId, Double sumRechargeValue) { this.deviceId = deviceId; this.sumRechargeValue = sumRechargeValue; } ... } 

所以這是您的方法的示例修復:

public List<TopUpRAMSInfo> listadoTOPUP2(Date fechaI, Date fechaF) {

    List<TopUpRAMSInfo> lista;

    CriteriaQuery<TopUpRAMS> data = cb.createQuery(TopUpRAMSInfo.class);
    Root<TopUpRAMS> c = data.from(TopUpRAMS.class);
    data.select(cb.construct(TopUpRAMSInfo.class,
            c.get("deviceId"), 
            cb.sum(c.get("rechargeValue"))
        )
    );
    data.where(cb.greaterThanOrEqualTo(c.get("connectionTime"), fechaI),
        cb.lessThanOrEqualTo(c.get("connectionTime"), fechaF)
    );
    data.groupBy(c.get("deviceId"));

    TypedQuery<TopUpRAMSInfo> datos = emDAO.createQuery(data);
    lista = datos.getResultList();
    return lista;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM