關(guān)于使用jpa聚合函數(shù)遇到的問題
使用jpa聚合函數(shù)遇到的問題
spring data jpa 可以通過在接口中按照規(guī)定語法創(chuàng)建一個方法進(jìn)行增刪改查,可以快速開發(fā)。
但是一些特殊情況,如按條件查詢統(tǒng)計(jì),這個時(shí)候通過規(guī)定語法還是直接@Query寫原生sql都不能解決,因?yàn)檫@個統(tǒng)計(jì)的條件不好添加。
百度之后,可以使用EntityManager來解決。
EntityManager 對象在一組實(shí)體類與底層數(shù)據(jù)源之間進(jìn)行 O/R 映射的管理。它可以用來管理和更新 Entity Bean, 根椐主鍵查找 Entity Bean, 還可以通過JPQL語句增刪改查實(shí)體。
首先通過@PersistenceContext注入EntityManager
@PersistenceContext private EntityManager em;
使用如下
BigDecimal totals = new BigDecimal(0);
StringBuffer sql= new StringBuffer("SELECT SUM(total) FROM Order WHERE state = 1");
if (StringUtils.isNotBlank(order.getOrderNo())) {
? ? sql.append(" AND orderNo = ").append(order.getOrderNo());
}
if (StringUtils.isNotBlank(orderTime)) {
? ? sql.append(" AND orderPayTime LIKE '").append(orderTime).append("%'");
}
if (order.getCustomer() != null) {
? ? //where條件后面是對象信息,不能直接傳入對象拼成sql,會報(bào)錯.
? ? sql.append(" AND customer = :customer");
}
Query query = em.createQuery(sql.toString());
if (order.getCustomer() != null) {
? ? //通過setParameter,給參數(shù)賦值.
? ? query.setParameter("customer", order.getCustomer());
}
Object result = query.getSingleResult();
if (result != null) {
? ? totals = new BigDecimal(result.toString());
}
return totals;jpa聚合函數(shù)(適用于聯(lián)合查詢)
最近幫老同事解決一個問題,場景是這樣的,查詢條件比較多,也就是我們說的聯(lián)合查詢,比如下面的,時(shí)間可以選不同的,狀態(tài)和來源也可以選不同,而且可選可不選

如果這個時(shí)候?qū)憇ql,是不是要各種條件判斷,各種糾結(jié),各種難寫,各種sql,這個時(shí)候大家一般都想到了springdata的jpa貌似很好用,可以直接拼接sql,但是怎么拼接呢,又怎么支持非表字段的展示呢,比如表中一個字段 aaa 好展示,但是查總和sum(aaa) ,怎么把這個作為一個字段展示呢。
不羅嗦了,直接上代碼
以下語句對應(yīng)的sql大概是
select count(***) from *** where *** group by ***
private List<Tuple> getCountByStatusOrSource(Integer status, Integer source, Integer userId, String startTime, String endTime, Integer timeSlot, String type) throws Exception {
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
Date sTime = new Date(), eTime = new Date();
CriteriaQuery<Tuple> query = cb.createTupleQuery();
Root<AAA> root = query.from(AAA.class);//AAA是對應(yīng)數(shù)據(jù)庫的類名,替換成自己的
Path<Integer> statusPath = root.get("status");
Path<String> statusNamePath = root.get("status").get("name");
Path<Integer> sourcePath = root.get("source");
Path<Date> operatorPath = root.get("operator");
List<Predicate> predicateList = new ArrayList<>();
if (source != null) {
predicateList.add(
cb.equal(sourcePath, source)
);
}
if (userId != null) {
predicateList.add(
cb.equal(operatorPath, userId)
);
}
Map timeMap = getChangedTime(startTime, endTime, timeSlot);//獲取時(shí)間的方法,具體代碼我就不沾了,自己寫個就行了
sTime = (Date) timeMap.get("sTime");
eTime = (Date) timeMap.get("eTime");
Expression<Date> startDateExpression = cb.literal(sTime);
Expression<Date> endDateExpression = cb.literal(eTime);
predicateList.add(
cb.between(updateTimePath, startDateExpression, endDateExpression)
);
Predicate[] predicates = new Predicate[predicateList.size()];
predicates = predicateList.toArray(predicates);
query.where(predicates);//where條件加上
if ("status".equals(type)) {
query.select(cb.tuple(statusPath, cb.count(root)));
query.groupBy(statusPath);
}
//query.multiselect(statusPath, cb.count(root));//
TypedQuery<Tuple> q = entityManager.createQuery(query);
List<Tuple> result = q.getResultList();
return result;
}這個sql,我們分別查到了兩個值 status 和數(shù)量,那么怎么獲取呢
循環(huán)一下那個獲取的list
Tuple tuple = list.get(i); (long)tuple.get(0)獲取的是數(shù)量 (Integer)tuple.get(1)獲取的是狀態(tài)id
到這是否全部清晰了呢,這個例子也適用sum,max等其他聚合函數(shù)
以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java?Elastic-Job分布式定時(shí)任務(wù)使用方法介紹
xxl-job?通過一個中心式的調(diào)度平臺,調(diào)度多個執(zhí)行器執(zhí)行任務(wù),調(diào)度中心通過?DB?鎖保證集群分布式調(diào)度的一致性,這樣擴(kuò)展執(zhí)行器會增大?DB?的壓力,然而大部分公司的任務(wù)數(shù),執(zhí)行器并不多;xxl-job?提供了非常好用的監(jiān)控頁面甚至還有任務(wù)失敗的郵件告警功能2023-01-01
獲取Java加載器和類完整結(jié)構(gòu)的方法分享
這篇文章主要為大家詳細(xì)介紹了獲取Java加載器和類完整結(jié)構(gòu)的方法,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)Java有一定的幫助,需要的可以參考一下2022-12-12
JavaWeb?Servlet實(shí)現(xiàn)文件上傳與下載功能實(shí)例
因自己負(fù)責(zé)的項(xiàng)目中需要實(shí)現(xiàn)文件上傳,所以下面下面這篇文章主要給大家介紹了關(guān)于JavaWeb?Servlet實(shí)現(xiàn)文件上傳與下載功能的相關(guān)資料,需要的朋友可以參考下2022-04-04
關(guān)于使用swagger整合springMVC的方法
在平時(shí)開發(fā)寫接口文檔的工作時(shí),一般都是word文檔,帶來書寫麻煩、維護(hù)麻煩的問題,比如改了源代碼忘了更新文檔、解釋不明確帶來歧義、無法在線嘗試等等,swagger可以有效解決這類問題,需要的朋友可以參考下2023-04-04
JAVA實(shí)現(xiàn)監(jiān)測tomcat是否宕機(jī)及控制重啟的方法
這篇文章主要介紹了JAVA實(shí)現(xiàn)監(jiān)測tomcat是否宕機(jī)及控制重啟的方法,可實(shí)現(xiàn)有效的檢測及控制tomcat服務(wù)器運(yùn)行,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-08-08
linux部署出現(xiàn)java文件操作報(bào)錯:java.io.FileNotFoundException解決辦法
這篇文章主要g介紹了linux部署出現(xiàn)java文件操作報(bào)錯:java.io.FileNotFoundException解決的相關(guān)資料,這個錯誤通常表示你的Spring Boot應(yīng)用程序無法找到指定的文本文件,需要的朋友可以參考下2023-12-12
JDBC獲取數(shù)據(jù)庫連接的5種方式實(shí)例
JDBC是一種用于執(zhí)行SQL語句的JavaAPI,為多種關(guān)系數(shù)據(jù)庫提供統(tǒng)一訪問,它由一組用Java語言編寫的類和接口組成,提供了諸如查詢和更新數(shù)據(jù)庫中數(shù)據(jù)的方法,這篇文章主要給大家介紹了關(guān)于JDBC獲取數(shù)據(jù)庫連接的5種方式,需要的朋友可以參考下2022-06-06

