亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

JPA的多表復(fù)雜查詢的方法示例

 更新時間:2019年08月04日 09:36:19   作者:alterem  
這篇文章主要介紹了JPA的多表復(fù)雜查詢的方法示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

最近工作中由于要求只能用hibernate+jpa 與數(shù)據(jù)庫進(jìn)行交互,在簡單查詢中,jpa繼承CrudRepository接口 ,然后利用jpa的方法命名規(guī)范進(jìn)行jpql查詢,然而在進(jìn)行復(fù)雜查詢時,需要繼承JpaSpecificationExecutor接口 利用Specification 進(jìn)行復(fù)雜查詢,由于我自己就遇到了這一問題,查了好多資料,雖然有方法,但是都沒有一個詳細(xì)的講解,以至于知道方法而不能很好的利用jpa復(fù)雜查詢的方便之處。我將舉幾個栗子,來詳細(xì)的說一下我自己在使用jpa多表復(fù)雜查詢的場景和想法。
栗子1:

以一個實體類User中的幾個屬性進(jìn)行篩選。

1. 名字
2. ID
3. 手機(jī)號
這是一個單表的多條件復(fù)雜查詢,由于是在幾個屬性中進(jìn)行篩選,其中的屬性的個數(shù)不知道有多少個,所以只需要利用Specification 查詢就可以很方便的實現(xiàn)這個需求。 下面請看代碼:
場景:頁面上通過條件篩選,查詢用戶列表

這里有3個條件 在頁面上我設(shè)置的id分別為searchName,searchId,searchMobile。 由于這個是user表 所以userRepository 繼承JpaSpecificationExecutor接口,隨后我創(chuàng)建了一個封裝條件的類

public class PageParam<T> {
  private Integer pageSize = 10;
  private Integer pageNumber = 1;
  private String searchName;
  private String searchMobile;
  private String searchId;
}

由于我這個方法是直接分頁的 所以pageNumber 和pageSize 也可以直接寫入到這個類中,用于方便接收參數(shù),主要是對下面3個參數(shù)的封裝

Specification<T> specification = new Specification<T>() {

  @Override
  public Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
    List<Predicate> list = new ArrayList<Predicate>();

    if (StringUtils.isNotBlank(searchName)) {
      list.add(cb.like(root.get("name").as(String.class), "%" + searchName + "%"));
    }

    if (StringUtils.isNotBlank(searchId)) {
      list.add(cb.equal(root.get("id").as(Long.class), searchId));
    }

    if (StringUtils.isNotBlank(searchMobile)) {
      list.add(cb.like(root.get("mobile").as(String.class), "%" + searchMobile + "%"));
    }

    Predicate[] p = new Predicate[list.size()];
    return cb.and(list.toArray(p));
  };
};

這里因為都是一個表,所以只要root.get(‘N ‘)這個N對應(yīng)所要查的 屬性的名字就好,屬性名 屬性名 重要的事情說三遍。
再接下來看一組多表的查詢

栗子2:

這里有4張表

public class Living {
  Long id;
  
  @ManyToOne
  @JsonIgnore
  @JoinColumn(name = "actorId", foreignKey = @ForeignKey(name = "none", value =ConstraintMode.NO_CONSTRAINT))
  public Actor actor;
  
  @ManyToOne
  @JsonIgnore
  @JoinColumn(name = "regionId", foreignKey = @ForeignKey(name = "none", value =ConstraintMode.NO_CONSTRAINT))
  public Region region;
}
  
public class Actor {
  Long id;
  
  @OneToMany(cascade = { CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH }, fetch = FetchType.LAZY)
  @JoinColumn(name = "actorId")
  @org.hibernate.annotations.ForeignKey(name = "none")
  List<Living> livings = new ArrayList<>();
  
  @OneToOne(cascade = { CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH }, fetch = FetchType.LAZY)
  @org.hibernate.annotations.ForeignKey(name = "none")
  @JoinColumn(name = "userDetailId", foreignKey = @ForeignKey(name = "none", value = ConstraintMode.NO_CONSTRAINT))
  UserDetail userDetail;
  
  @Column(nullable = false)
  @Enumerated(value = EnumType.ORDINAL)
  ActorType actorType = ActorType.A;
  
  public enum ActorType{
    A,B,C
  }
}
  
public class UserDetail {
  Long id; 
  
  @OneToOne(cascade = { CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH }, fetch = FetchType.LAZY)
  @org.hibernate.annotations.ForeignKey(name = "none")
  @JoinColumn(name = "actorId", foreignKey = @ForeignKey(name = "none", value = ConstraintMode.NO_CONSTRAINT))
  Actor actor;
  
  String truename;
}
  
public class Region {
  Long id;
  
  String name;
  
  @OneToMany(cascade = { CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH }, fetch = FetchType.LAZY)
  @JoinColumn(name = "regionId")
  @org.hibernate.annotations.ForeignKey(name = "none")
  List<Living> Livings;
}

現(xiàn)在要根據(jù)userdetai 種的 sex actor中的actortype 還有 region的id 為條件查詢出滿足條件的living。

public class PageParam<Living> {
  private Integer pageSize = 10;
  private Integer pageNumber = 1;
  private Sex sex;
  private ActorType actortype;
  private Long cityid;

首先我還是封裝了這樣一個類,但是這里的泛型 我是直接給到了想要的查詢結(jié)果的泛型,接下來 因為這里涉及到了一個 多表的查詢 所以上面的單表查詢的例子 已經(jīng)不適合這個查詢了,但是Criteria 的join方法 給我們提供了一個模式

Specification<Living> specification = new Specification<Living>() {

  @Override
  public Predicate toPredicate(Root<Living> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
    List<Predicate> list = new ArrayList<Predicate>();

    if (null!=sex) {
      Join<UserDetail, Living> join = root.join("actor", JoinType.LEFT);
      list.add(cb.equal(join.get("userDetail").get("sex"), sex ));
    }

    if (null!=actortype) {
      Join<Actor, Living> join = root.join("actor", JoinType.LEFT);
      list.add(cb.equal(join.get("actorType"), actortype));
    }
    if (null!=cityid) {
      Join<Region, Living> join = root.join("region", JoinType.LEFT);
      list.add(cb.equal(join.get("id"), cityid));
    }

    //Join<A, B> join = root.join("bs", JoinType.LEFT);
    //list.add(cb.equal(join.get("c").get("id"), id));
    Predicate[] p = new Predicate[list.size()];
    return cb.and(list.toArray(p));
  };
};

這里是我對條件進(jìn)行的封裝。jpa 的多條件查詢 主要是根據(jù)Criteria 為我們提供的方法封裝條件,然后根據(jù) 給條件定義的位置,再生成sql語句,之后完成查詢。

不得不說的地方,在這個多表的查詢中以下面這句為例

Join<UserDetail, Living> join = root.join("actor", JoinType.LEFT);
list.add(cb.equal(join.get("userDetail").get("sex"), sex ));

jointype.LEFT主要是說最終的這個屬性 是在哪個表中, 而前面的 “actor” 則表示 從living表中 查詢的 第一步的查詢,比如我給出的例子 是要查詢出 living 中的 actor 然后是actor 中的userdetail 之后才是 userdetail中的 sex屬性 所以下面的join.get(“userDetail”).get(“sex”) ,這里就是get出相應(yīng)的屬性,一直到你得到想要的屬性為止。 接下來的兩個屬性 也同理,許多人多jpa 有很大的誤解,認(rèn)為jpa 的多表,多條件復(fù)雜查詢,不如mybatis的查詢,在之前我也是這么覺得,但自從通過jpa 實現(xiàn)了這個多表多條件的復(fù)雜查詢之后,我覺得hibernate的復(fù)雜查詢 不遜于mybatis ,尤其是對sql 語句不是很精通的 碼農(nóng),雖然hibernate的門檻較高可jpa 恰恰降低了hibernate 所需要的門檻,希望大家可以通過我的經(jīng)驗,更方便的與數(shù)據(jù)庫進(jìn)行交互。

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

相關(guān)文章

  • Maven引用自定義jar包方式

    Maven引用自定義jar包方式

    這篇文章主要介紹了Maven引用自定義jar包方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • 使用@ConfigurationProperties實現(xiàn)類型安全的配置過程

    使用@ConfigurationProperties實現(xiàn)類型安全的配置過程

    這篇文章主要介紹了使用@ConfigurationProperties實現(xiàn)類型安全的配置過程,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • 解決idea中debug工具欄消失后如何顯示的問題

    解決idea中debug工具欄消失后如何顯示的問題

    這篇文章主要介紹了解決idea中debug工具欄消失后如何顯示的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-02-02
  • 解決在IDEA中創(chuàng)建多級package的問題

    解決在IDEA中創(chuàng)建多級package的問題

    這篇文章主要介紹了解決在IDEA中創(chuàng)建多級package的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-02-02
  • 如何利用java中String類的substring()字符串截取最后一個字符

    如何利用java中String類的substring()字符串截取最后一個字符

    Java中的String是不可變的類型,因此substring()方法并不會改變原字符串,而是返回了一個新的字符串,這篇文章主要介紹了如何利用java中String類的substring()字符串截取最后一個字符,需要的朋友可以參考下
    2023-11-11
  • 簡單談?wù)凴xJava和多線程并發(fā)

    簡單談?wù)凴xJava和多線程并發(fā)

    認(rèn)識RxJava已經(jīng)有一段時間了,但是一直沒有機(jī)會在項目中嘗試,最近在新的項目里引進(jìn)了RxJava寫一些事件處理,在review代碼的時候發(fā)現(xiàn)了一些和多線程并發(fā)相關(guān)的問題,所以寫了這篇文章,需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-03-03
  • Java的幾個重要版本_動力節(jié)點(diǎn)Java學(xué)院整理

    Java的幾個重要版本_動力節(jié)點(diǎn)Java學(xué)院整理

    jdk8 將在2014年3月份發(fā)布,迄今為止,可能是最大更新的java版本,也是令人期待的一個版本,在Java中引入閉包概念對Java程序開發(fā)方法的影響甚至?xí)笥贘ava5中引入的泛型特征對編程方式帶來的影響
    2017-06-06
  • 如何更優(yōu)雅的關(guān)閉java文本、網(wǎng)絡(luò)等資源

    如何更優(yōu)雅的關(guān)閉java文本、網(wǎng)絡(luò)等資源

    這篇文章主要介紹了如何更優(yōu)雅的關(guān)閉java文本、網(wǎng)絡(luò)等資源,在 finally 的關(guān)閉代碼中,還要再來一個 try/catch,看著是不是很難受,很不優(yōu)雅,很想干掉這個 finally!,需要的朋友可以參考下
    2019-06-06
  • Jlabel實現(xiàn)內(nèi)容自動換行簡單實例

    Jlabel實現(xiàn)內(nèi)容自動換行簡單實例

    這篇文章主要介紹了Jlabel實現(xiàn)內(nèi)容自動換行簡單實例,具有一定借鑒價值,需要的朋友可以參考下
    2018-01-01
  • SpringCloud feign微服務(wù)調(diào)用之間的異常處理方式

    SpringCloud feign微服務(wù)調(diào)用之間的異常處理方式

    這篇文章主要介紹了SpringCloud feign微服務(wù)調(diào)用之間的異常處理方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-06-06

最新評論