最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

jpa多條件查詢重寫(xiě)Specification的toPredicate方法

 更新時(shí)間:2021年11月23日 08:42:25   作者:韓小文  
這篇文章主要介紹了多條件查詢重寫(xiě)Specification的toPredicate方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

Spring Data JPA支持JPA2.0的Criteria查詢,相應(yīng)的接口是JpaSpecificationExecutor。

Criteria 查詢:是一種類(lèi)型安全和更面向?qū)ο蟮牟樵?。

這個(gè)接口基本是圍繞著Specification接口來(lái)定義的, Specification接口中只定義了如下一個(gè)方法:

Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder cb);

要理解這個(gè)方法,以及正確的使用它,就需要對(duì)JPA2.0的Criteria查詢有一個(gè)足夠的熟悉和理解,因?yàn)檫@個(gè)方法的參數(shù)和返回值都是JPA標(biāo)準(zhǔn)里面定義的對(duì)象。

Criteria查詢基本概念

Criteria 查詢是以元模型的概念為基礎(chǔ)的,元模型是為具體持久化單元的受管實(shí)體定義的,這些實(shí)體可以是實(shí)體類(lèi),嵌入類(lèi)或者映射的父類(lèi)。

  • CriteriaQuery接口:代表一個(gè)specific的頂層查詢對(duì)象,它包含著查詢的各個(gè)部分,比如:select 、from、where、group by、order by等 注意:CriteriaQuery對(duì)象只對(duì)實(shí)體類(lèi)型或嵌入式類(lèi)型的Criteria查詢起作用
  • Root接口:代表Criteria查詢的根對(duì)象,Criteria查詢的查詢根定義了實(shí)體類(lèi)型,能為將來(lái)導(dǎo)航獲得想要的結(jié)果,它與SQL查詢中的FROM子句類(lèi)似

1:Root實(shí)例是類(lèi)型化的,且定義了查詢的FROM子句中能夠出現(xiàn)的類(lèi)型。

2:查詢根實(shí)例能通過(guò)傳入一個(gè)實(shí)體類(lèi)型給 AbstractQuery.from方法獲得。

3:Criteria查詢,可以有多個(gè)查詢根。

4:AbstractQuery是CriteriaQuery 接口的父類(lèi),它提供得到查詢根的方法。CriteriaBuilder接口:用來(lái)構(gòu)建CritiaQuery的構(gòu)建器對(duì)象Predicate:一個(gè)簡(jiǎn)單或復(fù)雜的謂詞類(lèi)型,其實(shí)就相當(dāng)于條件或者是條件組合。

Criteria查詢基本對(duì)象的構(gòu)建

1:通過(guò)EntityManager的getCriteriaBuilder或EntityManagerFactory的getCriteriaBuilder方法可以得到CriteriaBuilder對(duì)象

2:通過(guò)調(diào)用CriteriaBuilder的createQuery或createTupleQuery方法可以獲得CriteriaQuery的實(shí)例

3:通過(guò)調(diào)用CriteriaQuery的from方法可以獲得Root實(shí)例過(guò)濾條件

  • A:過(guò)濾條件會(huì)被應(yīng)用到SQL語(yǔ)句的FROM子句中。在criteria 查詢中,查詢條件通過(guò)Predicate或Expression實(shí)例應(yīng)用到CriteriaQuery對(duì)象上。
  • B:這些條件使用 CriteriaQuery .where 方法應(yīng)用到CriteriaQuery 對(duì)象上
  • C:CriteriaBuilder也作為Predicate實(shí)例的工廠,通過(guò)調(diào)用CriteriaBuilder 的條件方( equalnotEqual, gt, ge,lt, le,between,like等)創(chuàng)建Predicate對(duì)象。
  • D:復(fù)合的Predicate 語(yǔ)句可以使用CriteriaBuilder的and, or andnot 方法構(gòu)建。

構(gòu)建簡(jiǎn)單的Predicate示例:

Predicate p1=cb.like(root.get(“name”).as(String.class), “%”+uqm.getName()+“%”);
Predicate p2=cb.equal(root.get("uuid").as(Integer.class), uqm.getUuid());
Predicate p3=cb.gt(root.get("age").as(Integer.class), uqm.getAge());

構(gòu)建組合的Predicate示例:

Predicate p = cb.and(p3,cb.or(p1,p2));

下面我們用兩個(gè)示例代碼來(lái)更深入的了解

復(fù)雜條件多表查詢

//需要查詢的對(duì)象
public class Qfjbxxdz {
    @Id
    @GeneratedValue(generator = "system-uuid")
    @GenericGenerator(name = "system-uuid", strategy = "uuid.hex")
    private String id;
    @OneToOne
    @JoinColumn(name = "qfjbxx")
    private Qfjbxx qfjbxx; //關(guān)聯(lián)表
    private String fzcc;
    private String fzccName;
    @ManyToOne
    @JoinColumn(name = "criminalInfo")
    private CriminalInfo criminalInfo;//關(guān)聯(lián)表
    @Column(length=800)
    private String bz;
    //get/set......
}
//創(chuàng)建構(gòu)造Specification的方法
//這里我傳入兩個(gè)條件參數(shù)因?yàn)榕c前段框架有關(guān),你們寫(xiě)的時(shí)候具體自己業(yè)務(wù)自行決斷
private Specification<Qfjbxxdz> getWhereClause(final JSONArray condetion,final JSONArray search) {
        return new Specification<Qfjbxxdz>() {
            @Override
            public Predicate toPredicate(Root<Qfjbxxdz> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                List<Predicate> predicate = new ArrayList<>();
                Iterator<JSONObject> iterator = condetion.iterator();
                Predicate preP = null;
                while(iterator.hasNext()){
                    JSONObject jsonObject = iterator.next();
                    //注意:這里用的root.join 因?yàn)槲覀円胵fjbxx對(duì)象里的字段作為條件就必須這樣做join方法有很多重載,使用的時(shí)候可以多根據(jù)自己業(yè)務(wù)決斷
                    Predicate p1 = cb.equal(root.join("qfjbxx").get("id").as(String.class),jsonObject.get("fzId").toString());
                    Predicate p2 = cb.equal(root.get("fzcc").as(String.class),jsonObject.get("ccId").toString());
                    if(preP!=null){
                        preP = cb.or(preP,cb.and(p1,p2));
                    }else{
                        preP = cb.and(p1,p2);
                    }
                }
                JSONObject jsonSearch=(JSONObject) search.get(0);
                Predicate p3=null;
                if(null!=jsonSearch.get("xm")&&jsonSearch.get("xm").toString().length()>0){
                   p3=cb.like(root.join("criminalInfo").get("xm").as(String.class),"%"+jsonSearch.get("xm").toString()+"%");
                }
                Predicate p4=null;
                if(null!=jsonSearch.get("fzmc")&&jsonSearch.get("fzmc").toString().length()>0){
                    p4=cb.like(root.join("qfjbxx").get("fzmc").as(String.class),"%"+jsonSearch.get("fzmc").toString()+"%");
                }
                Predicate preA;
                if(null!=p3&&null!=p4){
                    Predicate  preS =cb.and(p3,p4);
                    preA =cb.and(preP,preS);
                }else if(null==p3&&null!=p4){
                    preA=cb.and(preP,p4);
                }else if(null!=p3&&null==p4){
                    preA=cb.and(preP,p3);
                }else{
                    preA=preP;
                }
                predicate.add(preA);
                Predicate[] pre = new Predicate[predicate.size()];
                query.where(predicate.toArray(pre));
                return query.getRestriction();
            }

編寫(xiě)DAO類(lèi)或接口

dao類(lèi)/接口 需繼承

public interface JpaSpecificationExecutor<T> 

接口;

如果需要分頁(yè),還可繼承

public interface PagingAndSortingRepository<T, ID extends Serializable> extends CrudRepository<T, ID> 

JpaSpecificationExecutor 接口具有方法

    Page<T> findAll(Specification<T> spec, Pageable pageable);  //分頁(yè)按條件查詢  
    List<T> findAll(Specification<T> spec);    //不分頁(yè)按條件查詢 

方法。 我們可以在Service層調(diào)用這兩個(gè)方法。

兩個(gè)方法都具有 Specification spec 參數(shù),用于設(shè)定查詢條件。

Service 分頁(yè)+多條件查詢 調(diào)用示例:

studentInfoDao.findAll(new Specification<StudentInfo> () { 
   public Predicate toPredicate(Root<StudentInfo> root,  
     CriteriaQuery<?> query, CriteriaBuilder cb) {  
    Path<String> namePath = root.get("name");  
    Path<String> nicknamePath = root.get("nickname");  
    /** 
         * 連接查詢條件, 不定參數(shù),可以連接0..N個(gè)查詢條件 
         */  
    query.where(cb.like(namePath, "%李%"), cb.like(nicknamePath, "%王%")); //這里可以設(shè)置任意條查詢條件 
    return null;  
   } 
  }, page); 
 } 

這里通過(guò)CriteriaBuilder 的like方法創(chuàng)建了兩個(gè)查詢條件, 姓名(name)字段必須包含“李”, 昵稱(chēng)(nickname)字段必須包含“王”。

然后通過(guò)連接多個(gè)查詢條件即可。 這種方式使用JPA的API設(shè)置了查詢條件,所以不需要再返回查詢條件Predicate給Spring Data Jpa,故最后return null;即可。

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • SpringBoot啟動(dòng)器Starters使用及原理解析

    SpringBoot啟動(dòng)器Starters使用及原理解析

    這篇文章主要介紹了SpringBoot啟動(dòng)器Starters使用及原理解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-04-04
  • 快速學(xué)習(xí)JavaWeb中監(jiān)聽(tīng)器(Listener)的使用方法

    快速學(xué)習(xí)JavaWeb中監(jiān)聽(tīng)器(Listener)的使用方法

    這篇文章主要幫助大家快速學(xué)習(xí)JavaWeb中監(jiān)聽(tīng)器(Listener)的使用方法,感興趣的小伙伴們可以參考一下
    2016-09-09
  • Spring的Ioc模擬實(shí)現(xiàn)詳細(xì)介紹

    Spring的Ioc模擬實(shí)現(xiàn)詳細(xì)介紹

    這篇文章主要介紹了Spring的Ioc模擬實(shí)現(xiàn)詳細(xì)介紹,具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-11-11
  • SpringBoot3實(shí)現(xiàn)Gzip壓縮優(yōu)化的技術(shù)指南

    SpringBoot3實(shí)現(xiàn)Gzip壓縮優(yōu)化的技術(shù)指南

    隨著 Web 應(yīng)用的用戶量和數(shù)據(jù)量增加,網(wǎng)絡(luò)帶寬和頁(yè)面加載速度逐漸成為瓶頸,為了減少數(shù)據(jù)傳輸量,提高用戶體驗(yàn),我們可以使用 Gzip 壓縮 HTTP 響應(yīng),本文將介紹如何在 Spring Boot 3 中實(shí)現(xiàn) Gzip 壓縮優(yōu)化,需要的朋友可以參考下
    2025-04-04
  • Java Collections.sort()排序代碼案例

    Java Collections.sort()排序代碼案例

    這篇文章主要介紹了Java Collections.sort()排序代碼案例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-02-02
  • Spring注解方式無(wú)法掃描Service注解的解決

    Spring注解方式無(wú)法掃描Service注解的解決

    這篇文章主要介紹了Spring注解方式無(wú)法掃描Service注解的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • java中進(jìn)程與線程_三種實(shí)現(xiàn)方式總結(jié)(必看篇)

    java中進(jìn)程與線程_三種實(shí)現(xiàn)方式總結(jié)(必看篇)

    下面小編就為大家?guī)?lái)一篇java中進(jìn)程與線程_三種實(shí)現(xiàn)方式總結(jié)(必看篇)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-06-06
  • Spring中的@ComponentScan注解詳解

    Spring中的@ComponentScan注解詳解

    這篇文章主要介紹了Spring中的@ComponentScan注解詳解,ComponentScan做的事情就是告訴Spring從哪里找到bean,由你來(lái)定義哪些包需要被掃描,一旦你指定了,Spring將會(huì)在被指定的包及其下級(jí)包中尋找bean,需要的朋友可以參考下
    2024-01-01
  • 兩天沒(méi)解決的問(wèn)題chatgpt用了5秒搞定隱藏bug

    兩天沒(méi)解決的問(wèn)題chatgpt用了5秒搞定隱藏bug

    這篇文章主要為大家描述了我用了兩天沒(méi)解決的問(wèn)題chatgpt用了5秒搞定的全程介紹,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-04-04
  • Java批量向PDF文件中添加圖像水印實(shí)現(xiàn)細(xì)節(jié)

    Java批量向PDF文件中添加圖像水印實(shí)現(xiàn)細(xì)節(jié)

    這篇文章主要為大家介紹了Java批量向PDF文件中添加圖像水印實(shí)現(xiàn)細(xì)節(jié),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-05-05

最新評(píng)論

海晏县| 文安县| 临洮县| 昭苏县| 独山县| 东台市| 陵川县| 西平县| 渭源县| 雷波县| 中阳县| 烟台市| 札达县| 云龙县| 兰坪| 依兰县| 曲沃县| 望江县| 蕉岭县| 伊通| 姜堰市| 广昌县| 东至县| 南部县| 浦县| 青海省| 交城县| 苗栗县| 方山县| 江油市| 荔浦县| 鄱阳县| 石楼县| 潜江市| 乐亭县| 焦作市| 塔城市| 遂昌县| 大英县| 漳州市| 荔波县|