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

Spring JPA聯(lián)表查詢之OneToOne源碼詳解

 更新時間:2023年04月26日 11:41:22   作者:煙雨戲江南  
這篇文章主要為大家介紹了Spring JPA聯(lián)表查詢之OneToOne源碼詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

前言

前面幾篇我們學(xué)習(xí)的都是單表查詢,就是對一張表中的數(shù)據(jù)進(jìn)行查詢。而實際項目中,基本都會有多張表聯(lián)合查詢的情況,今天我們就來了解下JPA的聯(lián)表查詢是如做的。

源碼

@OneToOne 注解實現(xiàn)一對一關(guān)系映射。比如用戶跟車輛的關(guān)系(這里假設(shè)一個人只能有一輛車),一個用戶只能對應(yīng)一輛車,而一輛車同樣只能對應(yīng)一個用戶。
老規(guī)矩,在實例之前,我們先看看源碼:

public @interface OneToOne {
    Class targetEntity() default void.class;
    CascadeType[] cascade() default {};
    FetchType fetch() default EAGER;
    String mappedBy() default "";
    boolean orphanRemoval() default false;
}

注解屬性

  • targetEntity:(可選)表示默認(rèn)關(guān)聯(lián)的實體類型,默認(rèn)為當(dāng)前標(biāo)注的實體類
  • cascade:(可選)當(dāng)前類對象操作后級聯(lián)對象的操作。默認(rèn)為不級聯(lián)任何操作。
  • fetch:(可選)關(guān)聯(lián)是否延遲加載或者立刻加載。立刻加載是立刻獲取關(guān)聯(lián)的實體;延遲加載是表示關(guān)系類在被訪問時才加載。默認(rèn)值EAGER,也就是立刻加載。
  • mappedBy:(可選)擁有關(guān)聯(lián)關(guān)系的域,如果關(guān)系是單向的就不需要;如果是雙向關(guān)系表,那么擁有關(guān)系的這一方有建立、解除和更新與另一方關(guān)系的能力,而另一方?jīng)]有,只能被動管理,這個屬性被定義在關(guān)系的被擁有方
  • orphanRemoval:(可選)是否將刪除操作應(yīng)用于具有已從關(guān)系中刪除,并將刪除操作級聯(lián)到這些實體。

單向聯(lián)表

我這里所說的單向聯(lián)表就是只有一方添加注解;通俗講就是我可以通過 user 獲取到其 car 的信息,而不同通過 car 獲取到其 user 的信息。

user 實體類

@Entity
@Data
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;
    private String name;
    private int age;
    @OneToOne
    @JoinColumn(name = "car_id")
    private Car car;
}

car 實體類

@Data
@Entity
public class Car {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;
    private String name;
}

執(zhí)行請求 /user/findById?id=1,控制臺打印如下:

Hibernate: 
    select
        user0_.id as id1_1_0_,
        user0_.age as age2_1_0_,
        user0_.car_id as car_id4_1_0_,
        user0_.name as name3_1_0_,
        car1_.id as id1_0_1_,
        car1_.name as name2_0_1_ 
    from
        user user0_ 
    left outer join
        car car1_ 
            on user0_.car_id=car1_.id 
    where
        user0_.id=?

查詢結(jié)果

Optional[User(id=1, name=lili, age=11, car=Car(id=1, name=蘇A00001))]

從上面的 JPQL 語句我們可以發(fā)現(xiàn),uer 表car 表 是通過left outer jion進(jìn)行連接的。這樣我們可以通過查詢 user 信息來獲取其使用的 car 信息。

雙向聯(lián)表

我們除了需要通過 user 信息來獲取其 car 信息為,有時還需要通過 car 信息來獲取其 user 信息。只要再在 car 的實體中添加 user 字段,并添加@OneToOne注解。(這里有一個堆棧溢出的問題需要注意一下,詳情請見 JPA 錯題集 第二個報錯信息)

user 實體

@Entity
@Data
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;
    private String name;
    private int age;
    @OneToOne
    @JoinColumn(name = "car_id")
    @JsonIgnore
    private Car car;
}

car 實體

@Entity
@Data
public class Car {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;
    private String name;
    @OneToOne
    @JoinColumn(name = "user_id")
    @JsonIgnore
    private User user;
}

執(zhí)行請求 /car/findById?id=1,控制臺打印如下:

Hibernate: 
    select
        car0_.id as id1_0_0_,
        car0_.name as name2_0_0_,
        car0_.user_id as user_id3_0_0_,
        user1_.id as id1_2_1_,
        user1_.age as age2_2_1_,
        user1_.car_id as car_id4_2_1_,
        user1_.name as name3_2_1_,
        car2_.id as id1_0_2_,
        car2_.name as name2_0_2_,
        car2_.user_id as user_id3_0_2_ 
    from
        car car0_ 
    left outer join
        user user1_ 
            on car0_.user_id=user1_.id 
    left outer join
        car car2_ 
            on user1_.car_id=car2_.id 
    where
        car0_.id=?

查詢結(jié)果

Optional[Car(id=1, name=蘇A00001, user=com.example.sbjdemo.pojo.User@1c0775ea)] 用戶信息可以通過后面的實體類獲取

延遲加載(懶加載)

上面是 OneToOne 的情形,所以請求出來的數(shù)據(jù)也是比較有限的。試想一下,如果是 OneToMany,而我們只想獲取 one 的信息,但是 many 的數(shù)據(jù)卻跟著一起請求出來的,無論是從數(shù)據(jù)上還是性能上來講,都是一種負(fù)擔(dān)。那么,有沒有一種方法,讓我們能夠只獲取 one 的信息,而對于 many 可以動態(tài)獲取呢?這時,我們想到了源碼中一個 fetch 方法,他好像可以使用 LAZY 屬性來控制數(shù)據(jù)懶加載。廢話少說,上碼。

user 實體

User 實體類上的 Car 屬性中 @OneToOne 添加屬性 fetch = FetchType.LAZY

@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "car_id")
@JsonIgnore
private Car car;

執(zhí)行請求 /user/findById?id=1,控制臺打印如下:

Hibernate: 
    select
        user0_.id as id1_2_0_,
        user0_.age as age2_2_0_,
        user0_.car_id as car_id4_2_0_,
        user0_.name as name3_2_0_ 
    from
        user user0_ 
    where
        user0_.id=?

查詢結(jié)果:

Optional[com.example.sbjdemo.pojo.User@30c311e6] 通過控制臺可以看出,只有一個用戶查詢的 sql,結(jié)果也就是一個 user 的實體類數(shù)據(jù)。那我們的 car 信息該如何查看呢?其實我們可以使用查詢結(jié)果 resultget 我們所需要的數(shù)據(jù),如下圖所示:

查詢完會發(fā)現(xiàn),控制臺又打印了一個 JPQL:

Hibernate: 
    select
        car0_.id as id1_0_0_,
        car0_.name as name2_0_0_,
        car0_.user_id as user_id3_0_0_,
        user1_.id as id1_2_1_,
        user1_.age as age2_2_1_,
        user1_.car_id as car_id4_2_1_,
        user1_.name as name3_2_1_ 
    from
        car car0_ 
    left outer join
        user user1_ 
            on car0_.user_id=user1_.id 
    where
        car0_.id=?

恍然大悟,原來還是通過 sql 去完成的。

最后結(jié)論

oneToOne 主要針對一對一的場景,他們雙方都可以作為維護(hù)端或者被維護(hù)端,所以 mappedBy 這個屬性可有可無。這也要是與其他三個映射關(guān)系不同的地方。

以上就是Spring JPA聯(lián)表查詢之OneToOne源碼詳解的詳細(xì)內(nèi)容,更多關(guān)于Spring JPA聯(lián)表查詢的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • SpringBoot項目部署時application.yml文件的加載優(yōu)先級和啟動腳本問題

    SpringBoot項目部署時application.yml文件的加載優(yōu)先級和啟動腳本問題

    Spring Boot在啟動時會根據(jù)一定的優(yōu)先級順序加載配置文件,優(yōu)先級從高到低依次是:命令行參數(shù)、Jar包外部config目錄下的配置文件、Jar包同級目錄下的配置文件、classpath下的/config目錄、classpath根路徑
    2024-09-09
  • Java中Socket下載一個文本文件

    Java中Socket下載一個文本文件

    這篇文章主要介紹了Socket下載一個文本文件的實例代碼,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2017-06-06
  • Spring中的BeanFactory工廠詳細(xì)解析

    Spring中的BeanFactory工廠詳細(xì)解析

    這篇文章主要介紹了Spring中的BeanFactory工廠詳細(xì)解析,Spring的本質(zhì)是一個bean工廠(beanFactory)或者說bean容器,它按照我們的要求,生產(chǎn)我們需要的各種各樣的bean,提供給我們使用,需要的朋友可以參考下
    2023-12-12
  • 解析MyBatis源碼實現(xiàn)自定義持久層框架

    解析MyBatis源碼實現(xiàn)自定義持久層框架

    這篇文章主要介紹了手撕MyBatis源碼實現(xiàn)自定義持久層框架,涉及到的設(shè)計模式有Builder構(gòu)建者模式、??模式、代理模式,本文通過示例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2022-05-05
  • Spring集成MyBatis框架

    Spring集成MyBatis框架

    本文主要介紹了Spring集成MyBatis的配置和使用,項目基于Maven構(gòu)建,連接Mysql數(shù)據(jù)庫。下面跟著小編一起來看下吧
    2017-02-02
  • java 面試題閏年判斷詳解及實例

    java 面試題閏年判斷詳解及實例

    這篇文章主要介紹了java面試題 閏年判斷的相關(guān)資料,需要的朋友可以參考下
    2017-03-03
  • Java SQL注入案例教程及html基礎(chǔ)入門

    Java SQL注入案例教程及html基礎(chǔ)入門

    這篇文章主要介紹了前端開發(fā)每天必學(xué)之SQL及HTML入門基礎(chǔ)知識,介紹了學(xué)習(xí)web前端開發(fā)需要掌握的基礎(chǔ)技術(shù),感興趣的小伙伴們可以參考一下
    2021-07-07
  • 淺談MyBatis通用Mapper實現(xiàn)原理

    淺談MyBatis通用Mapper實現(xiàn)原理

    這篇文章主要介紹了淺談MyBatis通用Mapper實現(xiàn)原理,本文會先介紹通用 Mapper 的簡單原理,然后使用最簡單的代碼來實現(xiàn)這個過程。感興趣的小伙伴們可以參考一下
    2018-10-10
  • java開發(fā)https請求ssl不受信任問題解決方法

    java開發(fā)https請求ssl不受信任問題解決方法

    這篇文章主要介紹了java開發(fā)https請求ssl不受信任問題解決方法,具有一定借鑒價值,需要的朋友可以參考下
    2018-01-01
  • Springboot 如何獲取上下文對象

    Springboot 如何獲取上下文對象

    這篇文章主要介紹了Springboot 如何獲取上下文對象的方法,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-08-08

最新評論

焦作市| 江都市| 东乌珠穆沁旗| 栖霞市| 凭祥市| 长葛市| 四平市| 阿拉尔市| 湘乡市| 信阳市| 滦南县| 大石桥市| 灵石县| 离岛区| 中卫市| 龙泉市| 丘北县| 庄河市| 辽宁省| 新丰县| 香港| 寻乌县| 迁西县| 阿拉尔市| 保德县| 仙游县| 丰都县| 甘洛县| 阿瓦提县| 合作市| 凉城县| 太仆寺旗| 清丰县| 平谷区| 迁西县| 宁南县| 会昌县| 定南县| 温泉县| 南木林县| 黎城县|