国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

JPA的多表復(fù)雜查詢

chaos_G / 3440人閱讀

摘要:我將舉幾個(gè)栗子,來詳細(xì)的說一下我自己在使用多表復(fù)雜查詢的場景和想法。名字手機(jī)號這是一個(gè)單表的多條件復(fù)雜查詢,由于是在幾個(gè)屬性中進(jìn)行篩選,其中的屬性的個(gè)數(shù)不知道有多少個(gè),所以只需要利用查詢就可以很方便的實(shí)現(xiàn)這個(gè)需求。

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

栗子1:

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

1. 名字
2. ID
3. 手機(jī)號

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

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

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

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

Specification specification = new Specification() {

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

        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));
    };
};

這里因?yàn)槎际且粋€(gè)表,所以只要root.get(‘N ‘)這個(gè)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 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 Livings;
}
    

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

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

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

Specification specification = new Specification() {

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

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

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

        //Join 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語句,之后完成查詢。
不得不說的地方,在這個(gè)多表的查詢中以下面這句為例

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

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

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/75774.html

相關(guān)文章

  • 我就是不看好jpa

    摘要:要是緊急排查個(gè)問題,媽蛋雖然有很多好處,比如和底層的無關(guān)。你的公司如果有,是不允許你亂用的。 知乎看到問題《SpringBoot開發(fā)使用Mybatis還是Spring Data JPA??》,順手一答,討論激烈。我實(shí)在搞不懂spring data jpa為啥選了hibernate作為它的實(shí)現(xiàn),是Gavin King的裙帶關(guān)系么?DAO層搞來搞去,從jdbc到hibernate,從top...

    NusterCache 評論0 收藏0
  • Mybatis單表CRUD與多表關(guān)聯(lián)的無SQL通用方案_2: 無SQL實(shí)現(xiàn)關(guān)聯(lián)查詢的自動(dòng)綁定

    摘要:對關(guān)聯(lián)另外的實(shí)體關(guān)聯(lián)查詢另外一張表的多個(gè)實(shí)體如部門實(shí)體對應(yīng)的對象中需要關(guān)聯(lián)多個(gè)子部門實(shí)體。對于關(guān)聯(lián)一個(gè)或多個(gè)實(shí)體的情況,一般通過的實(shí)現(xiàn)無的實(shí)現(xiàn)方案不寫,不通過的,要更優(yōu)雅的實(shí)現(xiàn)關(guān)聯(lián)的自動(dòng)綁定,一個(gè)主流的方案就是類似的注解了。 上一篇無SQL實(shí)現(xiàn)單表CRUD中我們已經(jīng)通過Mybatis-plus插件的通用Mapper實(shí)現(xiàn)了單表的CRUD的無SQL化,已經(jīng)可以有效減少M(fèi)ybatis的代碼量...

    30e8336b8229 評論0 收藏0
  • 幾個(gè)數(shù)據(jù)持久化框架Hibernate、JPA、Mybatis、JOOQ和JDBC Template的

    摘要:不管是還是,表之間的連接查詢,被映射為實(shí)體類之間的關(guān)聯(lián)關(guān)系,這樣,如果兩個(gè)實(shí)體類之間沒有實(shí)現(xiàn)關(guān)聯(lián)關(guān)系,你就不能把兩個(gè)實(shí)體或者表起來查詢。 因?yàn)轫?xiàng)目需要選擇數(shù)據(jù)持久化框架,看了一下主要幾個(gè)流行的和不流行的框架,對于復(fù)雜業(yè)務(wù)系統(tǒng),最終的結(jié)論是,JOOQ是總體上最好的,可惜不是完全免費(fèi),最終選擇JDBC Template。 Hibernate和Mybatis是使用最多的兩個(gè)主流框架,而JOO...

    xietao3 評論0 收藏0
  • 一起來學(xué)SpringBoot | 第六篇:整合SpringDataJpa

    摘要:忽略該字段的映射省略創(chuàng)建數(shù)據(jù)訪問層接口,需要繼承,第一個(gè)泛型參數(shù)是實(shí)體對象的名稱,第二個(gè)是主鍵類型。 SpringBoot 是為了簡化 Spring 應(yīng)用的創(chuàng)建、運(yùn)行、調(diào)試、部署等一系列問題而誕生的產(chǎn)物,自動(dòng)裝配的特性讓我們可以更好的關(guān)注業(yè)務(wù)本身而不是外部的XML配置,我們只需遵循規(guī)范,引入相關(guān)的依賴就可以輕易的搭建出一個(gè) WEB 工程 上一篇介紹了Spring JdbcTempl...

    Dionysus_go 評論0 收藏0

發(fā)表評論

0條評論

最新活動(dòng)
閱讀需要支付1元查看
<