[英]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。 可以解決這個問題
使用cb.and():
data.where(cb.and( cb.greaterThanOrEqualTo(c.get("connectionTime"), fechaI), cb.lessThanOrEqualTo(c.get("connectionTime"), fechaF) ) );
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實體。
有多種方法可以進行多選/投影:
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")));
CriteriaQuery類型將是Tuple
CriteriaQuery<Tuple> data = cb.createTupleQuery(); Root<TopUpRAMS> c = data.from(TopUpRAMS.class); data.multiselect(c.get("deviceId"), cb.sum(c.get("rechargeValue")));
使用構造函數
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.