spring-data-jpa之Specification使用exists和not exists

寫在前面

spring-data-jpa是spring對hibernate框架的封裝,如果你一開始熟悉的是mybatis,那麼轉到jpa可能會讓你有些不適應。jpa的簡單查詢確實非常非常方便,但是對於複雜查詢來說,jpa確實有點“複雜”。當然,你可以寫原生sql,但是那樣就違背了jpa操作對象、避免操作sql的出發點了。好,廢話不多說,進入正題吧。

 

遇到的問題

原先是針對單表的列表查詢操作,非常簡單,所以就用了Specification來做:

return (root, query, criteriaBuilder) -> {
            List<Predicate> predicates = Lists.newArrayList();
           
            //一些查詢條件,數量比較多
            if (deviceStatus != null && deviceStatus > 0) {
                //主要是這段,之前是單表的狀態查詢
                 if (DeviceFilterStatus.STOP_USE.getCode().equals(deviceStatus)) {
                    predicates.add(criteriaBuilder.equal(root.get("isUsing"),                         deviceStatus));
                } else {
                    predicates.add(criteriaBuilder.equal(root.get("online"), deviceStatus));
                }
            }
            Predicate[] predicateArr = new Predicate[predicates.size()];
            return criteriaBuilder.and(predicates.toArray(predicateArr));

        };

後來改了需求,查詢邏輯有所改變,涉及到第二張表,而我又不想推翻重新寫原生sql,那樣效率比較低(懶),去百度上瘋狂找,奈何沒答案,也問了很多人,紛紛表示沒有用過這樣的寫法。後來我去了spring官網看文檔,發現:

官網只有一些簡單例子,並沒有複雜查詢的介紹(可能得去看hibernate官網,不過我沒去看)。

so.....只能自己摸索

結果

我找了一下CriteriaBuilder的方法,發現存在exists的方法,那麼,接下來的問題就在於如何構建他的參數Subquery。

Subquery看字面意思是子查詢,顯然sql裏面exists後面的查詢得放在這裏面做

事情有了轉機,我發現第二個參數CriteriaQuery有構建子查詢的方法

然後我通過這個構建出子查詢

Subquery<DeviceAlarmEntity> subQuery = query.subquery(DeviceAlarmEntity.class);
                Root<DeviceAlarmEntity> subRoot = subQuery.from(XXX.class);
                //這裏是子查詢的條件,前者是自身的條件,後者是主表的關聯條件,當然where方法的參
//數是個可變參數,可以根據自己需要加條件
                subQuery.where(criteriaBuilder.equal(subRoot.get("valid"), true), criteriaBuilder.equal(root.get("deviceId"), subRoot.get("deviceId")));
                //這句話不加會報錯,因爲他不知道你子查詢要查出什麼字段
                subQuery.select(subRoot.get("id"));

最後,把上面的子查詢放進exists方法的參數就可以了,

如果是not exists,前面再嵌套not方法,下面是示例:

//exists
criteriaBuilder.exists(subQuery)

//not exists
criteriaBuilder.not(criteriaBuilder.exists(subQuery)

本文沒什麼深度,純粹經驗之談,希望能幫助到有同樣需求的你。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章