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

Spring Data JPA中的動態(tài)查詢實例

 更新時間:2017年04月01日 11:41:26   作者:anxpp  
本篇文章主要介紹了詳解Spring Data JPA中的動態(tài)查詢。小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

spring Data JPA大大的簡化了我們持久層的開發(fā),但是實際應(yīng)用中,我們還是需要動態(tài)查詢的。

比如,前端有多個條件,這些條件很多都是可選的,那么后端的SQL,就應(yīng)該是可以定制的,在使用hibernate的時候,可以通過判斷條件來拼接SQL(HQL),當(dāng)然,Spring Data JPA在簡化我們開發(fā)的同時,也是提供了支持的。

通過實現(xiàn)Criteria二實現(xiàn)的動態(tài)查詢,需要我們的Repo接口繼承JpaSpecificationExecutor接口,這是個泛型接口。

然后查詢的時候,傳入動態(tài)查詢參數(shù),分頁參數(shù)等即可。

使用起來很簡單,不過為了知其所以然,先介紹一下Criteria API。

Criteria API

如果編譯器能夠?qū)Σ樵儓?zhí)行語法正確性檢查,那么對于 Java 對象而言該查詢就是類型安全的。Java™Persistence API (JPA) 的 2.0 版本引入了 Criteria API,這個 API 首次將類型安全查詢引入到 Java 應(yīng)用程序中,并為在運行時動態(tài)地構(gòu)造查詢提供一種機制。本文介紹如何使用 Criteria API 和與之密切相關(guān)的 Metamodel API 編寫動態(tài)的類型安全查詢。

在使用Spring Data JPA的時候,只要我們的Repo層繼承JpaSpecificationExecutor接口就可以使用Specification進(jìn)行動態(tài)查詢了,我們先看下JpaSpecificationExecutor接口:

public interface JpaSpecificationExecutor<T> { 
 T findOne(Specification<T> spec); 
 List<T> findAll(Specification<T> spec); 
 Page<T> findAll(Specification<T> spec, Pageable pageable); 
 List<T> findAll(Specification<T> spec, Sort sort); 
 long count(Specification<T> spec); 
} 

可以看到提供了5個方法,方法的參數(shù)和返回值已經(jīng)很明顯的表達(dá)了其意圖。其中的參數(shù),Pageable和Sort應(yīng)該是比較簡單的,分別是分頁參數(shù)和排序參數(shù),而重點就是Specification參數(shù),先看下這個接口的定義:

public interface Specification<T> { 
 Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder cb); 
} 

其中就一個方法,返回的是動態(tài)查詢的數(shù)據(jù)結(jié)構(gòu)。

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

這里使用的都是Java EE中的規(guī)范,具體實現(xiàn)本人采用的是Hibernate,當(dāng)然也可以選擇其他實現(xiàn)了JPA規(guī)范的數(shù)據(jù)持久層框架。
這里需要再次回過頭看看Criteria API中的一些東西:

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

CriteriaQuery接口:代表一個specific的頂層查詢對象,它包含著查詢的各個部分,比如:select 、from、where、group by、order by等注意:CriteriaQuery對象只對實體類型或嵌入式類型的Criteria查詢起作用

Root接口:代表Criteria查詢的根對象,Criteria查詢的查詢根定義了實體類型,能為將來導(dǎo)航獲得想要的結(jié)果,它與SQL查詢中的FROM子句類似

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

2:查詢根實例能通過傳入一個實體類型給 AbstractQuery.from方法獲得。

3:Criteria查詢,可以有多個查詢根。

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

其中支持的方法非常之強大,下面給出一個示例,大家可以參考一下,同樣的,可以根據(jù)示例,自己可以寫出更為復(fù)雜的查詢:

Repo接口:

public interface DevHREmpConstrastDao 
 extends JpaRepository<DevHREmpConstrast, Long>,JpaSpecificationExecutor<DevHREmpConstrast> 

查詢實例1:

/** 
 * 條件查詢時動態(tài)組裝條件 
 */ 
private Specification<DevHREmpConstrast> where( 
  final String corg,final String name,final String type,final String date,final String checker){ 
 return new Specification<DevHREmpConstrast>() { 
  @Override 
  public Predicate toPredicate(Root<DevHREmpConstrast> root, CriteriaQuery<?> query, CriteriaBuilder cb) { 
   List<Predicate> predicates = new ArrayList<Predicate>(); 
   //機構(gòu) 
   if(corg!=null&&!corg.equals("")){ 
    List<String> orgIds = organizationDao.findByName("%"+corg+"%"); 
    if(orgIds.size()>0&&orgIds.size()<1000) 
     predicates.add(root.<String>get("confirmOrgNo").in(orgIds));//confirmOrgNo 
   } 
   //名字 
   if(name!=null&&!name.equals("")){ 
    List<String> userIds = userDao.findByName(name); 
    if(userIds.size()>0&&userIds.size()<1000)//如果太多就不管了這個條件了 
     predicates.add(root.<String>get("hrUserName").in(userIds)); 
   } 
   //類型 
   if(type!=null&&!type.equals("")) 
    predicates.add(cb.equal(root.<String>get("hrUpdateType"),type)); 
   //日期 
   if(date!=null&&!date.equals("")){ 
    //處理時間 
    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); 
    Date startDate; 
    Date endDate; 
    try { 
     startDate = format.parse(date); 
    } catch (ParseException e) { 
     startDate = new Date(946656000000L);//2000 01 01 
    } 
    endDate = startDate; 
    Calendar calendar = Calendar.getInstance() ; 
    calendar.setTime(endDate); 
    calendar.add(Calendar.DATE, 1); 
    endDate = calendar.getTime(); 
    calendar = null; 
    predicates.add(cb.between(root.<Date>get("insDate"),startDate,endDate)); 
   } 
   //審核人 
   if(checker!=null&&!checker.equals("")){ 
    List<String> userIds = userDao.findByName(checker); 
    if(userIds.size()>0&&userIds.size()<1000)//如果太多就不管了這個條件了 
     predicates.add(root.<String>get("confirmUserId").in(userIds)); 
   } 
   return query.where(predicates.toArray(new Predicate[predicates.size()])).getRestriction(); 
  } 
 }; 
} 

查詢實例2:

/** 
 * 條件查詢時動態(tài)組裝條件 
 */ 
 private Specification<DevHREmpConstrast> where( 
   final String corg,final String name,final String type,final String date,final String checker){ 
  return new Specification<DevHREmpConstrast>() { 
   @Override 
   public Predicate toPredicate(Root<DevHREmpConstrast> root, CriteriaQuery<?> query, CriteriaBuilder cb) { 
    List<Predicate> predicates = new ArrayList<Predicate>(); 
    //機構(gòu) 
    if(corg!=null&&!corg.equals("")){ 
     List<String> orgIds = organizationDao.findByName("%"+corg+"%"); 
     if(orgIds.size()>0&&orgIds.size()<1000) 
      predicates.add(root.<String>get("confirmOrgNo").in(orgIds));//confirmOrgNo 
    } 
    //名字 
    if(name!=null&&!name.equals("")){ 
     List<String> userIds = userDao.findByName(name); 
     if(userIds.size()>0&&userIds.size()<1000)//如果太多就不管了這個條件了 
      predicates.add(root.<String>get("hrUserName").in(userIds)); 
    } 
    //類型 
    if(type!=null&&!type.equals("")) 
     predicates.add(cb.equal(root.<String>get("hrUpdateType"),type)); 
    //日期 
    if(date!=null&&!date.equals("")){ 
     //處理時間 
     SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); 
     Date startDate; 
     Date endDate; 
     try { 
      startDate = format.parse(date); 
     } catch (ParseException e) { 
      startDate = new Date(946656000000L);//2000 01 01 
     } 
     endDate = startDate; 
     Calendar calendar = Calendar.getInstance() ; 
     calendar.setTime(endDate); 
     calendar.add(Calendar.DATE, 1); 
     endDate = calendar.getTime(); 
     calendar = null; 
     predicates.add(cb.between(root.<Date>get("insDate"),startDate,endDate)); 
    } 
    //審核人 
    if(checker!=null&&!checker.equals("")){ 
     List<String> userIds = userDao.findByName(checker); 
     if(userIds.size()>0&&userIds.size()<1000)//如果太多就不管了這個條件了 
      predicates.add(root.<String>get("confirmUserId").in(userIds)); 
    } 
    return query.where(predicates.toArray(new Predicate[predicates.size()])).getRestriction(); 
   } 
  }; 
 } 

然后調(diào)用dao層方法傳入where()方法返回的參數(shù)即可。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • JavaGUI常用三種布局使用介紹

    JavaGUI常用三種布局使用介紹

    這篇文章主要介紹了JavaGUI常用三種布局-FlowLayout、BorderLayout、GridLayout,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧
    2023-03-03
  • 詳解使用Spring Boot開發(fā)Web項目

    詳解使用Spring Boot開發(fā)Web項目

    這篇文章主要介紹了詳解使用Spring Boot開發(fā)Web項目,具有一定的參考價值,感興趣的小伙伴們可以參考一下。
    2017-04-04
  • 基于spring 方法級緩存的多種實現(xiàn)

    基于spring 方法級緩存的多種實現(xiàn)

    下面小編就為大家?guī)硪黄趕pring 方法級緩存的多種實現(xiàn)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-09-09
  • SpringBoot AOP使用筆記

    SpringBoot AOP使用筆記

    今天小編就為大家分享一篇關(guān)于SpringBoot AOP使用筆記,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-01-01
  • SpringBoot中MVC的自動配置詳解

    SpringBoot中MVC的自動配置詳解

    這篇文章主要介紹了SpringBoot中MVC的自動配置詳解,在實際開發(fā)過程中,還有一些老的系統(tǒng)在使用xml格式來傳輸數(shù)據(jù),SpringBoot也提供了xml格式數(shù)據(jù)的返回,只需要小小的改動,就可以實現(xiàn),需要的朋友可以參考下
    2023-09-09
  • java實現(xiàn)潛艇大戰(zhàn)游戲源碼

    java實現(xiàn)潛艇大戰(zhàn)游戲源碼

    潛艇大戰(zhàn)游戲相信大家都玩過,是一款非常有趣的小游戲,那么基于代碼是如何實現(xiàn)的呢?今天小編給大家?guī)硪黄坛處椭蠹覍W(xué)習(xí)java實現(xiàn)潛艇大戰(zhàn)游戲,感謝的朋友一起看看吧
    2021-06-06
  • Java實現(xiàn)數(shù)組反轉(zhuǎn)翻轉(zhuǎn)的方法實例

    Java實現(xiàn)數(shù)組反轉(zhuǎn)翻轉(zhuǎn)的方法實例

    本篇文章主要介紹了Java實現(xiàn)數(shù)組反轉(zhuǎn)翻轉(zhuǎn)的方法實例,詳細(xì)的介紹了3種實現(xiàn)方法,有興趣的可以了解一下。
    2017-04-04
  • springboot整合log4j的踩坑實戰(zhàn)記錄

    springboot整合log4j的踩坑實戰(zhàn)記錄

    log日志的重要性不言而喻,所以我們需要在系統(tǒng)內(nèi)根據(jù)實際的業(yè)務(wù)進(jìn)行日志的整合,下面這篇文章主要給大家介紹了關(guān)于springboot整合log4j的踩坑實戰(zhàn)記錄,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-04-04
  • 詳解如何在Java中重寫equals()和hashCode()方法

    詳解如何在Java中重寫equals()和hashCode()方法

    在 Java 中,equals() 和 hashCode() 方法是 Object 類中定義的重要方法,它們用于比較對象的相等性以及計算對象的哈希值,本文將詳細(xì)介紹如何在 Java 中重寫 equals() 和 hashCode() 方法,并討論其最佳實踐,需要的朋友可以參考下
    2024-08-08
  • Mybatis中單雙引號引發(fā)的慘案及解決

    Mybatis中單雙引號引發(fā)的慘案及解決

    這篇文章主要介紹了Mybatis中單雙引號引發(fā)的慘案及解決方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-01-01

最新評論

剑河县| 灵山县| 维西| 普兰店市| 兰西县| 法库县| 博客| 军事| 大英县| 英山县| 泸水县| 民勤县| 阳城县| 达日县| 拉萨市| 益阳市| 肃北| 鄂温| 梁河县| 武鸣县| 伊春市| 合作市| 小金县| 望江县| 密山市| 东乡族自治县| 八宿县| 陈巴尔虎旗| 荃湾区| 蓬安县| 丰台区| 郸城县| 云龙县| 垣曲县| 东丰县| 固原市| 道真| 灵石县| 芮城县| 阿尔山市| 沁阳市|