Jpa中Specification的求和sum不生效原理分析
引言
秋天的北京一如既往的沒太陽,分不清天上是云是霧或者又是什么奇奇怪怪的東西,建筑物不分黑白的證明著自己的輪廓。霧蒙蒙的天一眼望不到邊,就像我需要用到Spring Data Jpa 實現(xiàn)一個特別小的SQL,怎么寫都看不到我想要的效果一樣。
簡單的統(tǒng)計
想實現(xiàn)的SQL十分簡單,就是一個簡單的統(tǒng)計:
SELECT
activity_code,
activity_name,
sum(contact_user_nums),
conversion_step_code,
conversion_step
FROM
epm_estimate_main
WHERE
activity_code ='1'
GROUP BY
conversion_step_code
ORDER BY
contact_user_nums DESC;jpa實現(xiàn)方式
由于一些條條框框的原因,最終選擇用jpa的這種實現(xiàn)方式,想到這個玩意五分鐘寫完就能回家玩游戲,于是上來就寫:

但是查詢出來的結(jié)果卻不是很好看:第一,我沒有拿到想要的求和;第二,查詢出來的結(jié)果集包括所有字段;
好在分組和排序都按照預(yù)期的想法實現(xiàn)了。
方法
首先去B某搜索引擎上找,找來找去,大家的方法無非四種:
- 第一種:去XXX的JPA, MyBatis真香;
- 第二種:實在不行用JPQL;
- 第三種:自己創(chuàng)建CriteriaBuilder,CriteriaQuery及Root;
- 第四種:不知道怎么寫,等大腿。
國內(nèi)搜完,于是又去G某引擎上翻翻,老外似乎問的比較具體,但都沒找到我想要的答案(散裝的四級還是吃力);
翻看了一些網(wǎng)上的問題與解答,貌似出現(xiàn)了一個規(guī)律,用findAll方法實現(xiàn)Specification接口的文章似乎都有這個問題,而使用EntityManager自己來實現(xiàn)的小伙伴都不怎么關(guān)注。
findAll實現(xiàn)
赤裸裸的歧視,下定決心就要用這個findAll實現(xiàn)一把。
窗外的天色越來越暗,但是我覺得這么簡單的一個查詢居然浪費了我開黑的時間,不由得開始懷疑自己。不管我怎么對CriteriaQuery.multiselect操作,查詢出來得結(jié)果集都是包含所有字段,不由得開始懷疑multiselect這個方法為什么沒有生效,JpaSpecificationExecutor這個接口到底什么居心?
找到這個接口的API:有兩個實現(xiàn)類(其中QuerydslJpaRepository已顯示過期)

剩下的這個實現(xiàn)類SimpleJpaRepository中找到對應(yīng)的findAll方法,它調(diào)用了本類中的其他方法,一路向下找,最終在方法調(diào)用的末端,找到了其中的貓膩:

我在multiselect方法中的所有定義都被 query.select(root) 覆蓋掉了!
天色已晚,華燈初上,最后本來想重寫一下這個方法,但撇了一眼樓下的公交站,廣告牌的背景似乎有點過年的味道。
Spring Boot自動注冊了EntityManager
那段代碼最終變成這樣(Spring Boot自動注冊了EntityManager):
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<EstimateDO> query = builder.createQuery(EstimateDO.class);
Root<EstimateDO> root = query.from(EstimateDO.class);
query
.multiselect(
root.get("activityCode"),
root.get("activityName"),
builder.sum(root.get("contactUserNums").as(Long.class)).alias("contactUserNums"),
root.get("conversionStepCode"),
root.get("conversionStep")
);
List<Predicate> predicates = new ArrayList();
predicates.add(
builder.equal(root.get("activityCode").as(String.class), estimateDO.getActivityCode())
);
if (!StringUtils.isEmpty(estimateDO.getContactCode())) {
predicates.add(
builder.equal(root.get("contactCode").as(String.class), estimateDO.getContactCode())
);
}
query
.where(predicates.toArray(new Predicate[predicates.size()]))
.groupBy(root.get("conversionStepCode"))
.orderBy(builder.desc(root.get("contactUserNums")));
List<EstimateDO> list = entityManager.createQuery(query).getResultList();我的決心一文不值。
以上就是Jpa中Specification的求和sum不生效原理分析的詳細內(nèi)容,更多關(guān)于Jpa Specification sum不生效的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
SpringBoot集成EasyPoi實現(xiàn)Excel模板導(dǎo)出成PDF文件
在日常工作中,我們經(jīng)常需要將數(shù)據(jù)導(dǎo)出成Excel表格或PDF文件,本文將介紹如何在SpringBoot項目中集成EasyPoi和iText庫,從而實現(xiàn)Excel模板導(dǎo)出成PDF文件的功能,希望對大家有所幫助2025-07-07
關(guān)于在使用Lombok時maven?install找不到符號問題的解決辦法
Maven環(huán)境下開發(fā)項目時,尤其是涉及Lombok或其他依賴時,IDE會在構(gòu)建和編譯過程中進行注解處理,這篇文章主要介紹了關(guān)于在使用Lombok時maven?install找不到符號問題的解決辦法,需要的朋友可以參考下2025-10-10
java輸入時如何通過回車(enter)來結(jié)束輸入
這篇文章主要介紹了java輸入時如何通過回車(enter)來結(jié)束輸入,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-05-05
Maven 或 Gradle 下載和添加 jar 文件的最佳方式
Maven是一個Java項目管理工具,它可以幫助你管理項目的依賴、編譯、打包、測試和部署等過程,下面給大家介紹Maven或Gradle下載和添加jar文件的最佳方式,感興趣的朋友一起看看吧2024-10-10

