Mybatis高級查詢之一對一查詢的四種方法

[toc]html

1. 一對一查詢

1.1-1.3 咱們假設場景爲用戶和角色一對一,根據數據庫基本原理,咱們把外鍵設置在用戶一邊,即在實體類中添加角色這個屬性。數據庫

1.1 一對一嵌套結果查詢

1.1.1嵌套結果查詢的核心思想

  • 核心思想:直接用slect標籤經過數據庫字段和實體類字段的自動映射。
    • 首先在select語句中指明映射關係。
    • 而後咱們看resultType的值是一個實體類。
    • 自動映射到實體類。
  • 應用在場景中:咱們假設用戶和角色之間是一對一,在用戶類中一個屬性是角色 sysrole類型的,查詢用戶的時候把所歸屬的角色查詢出來,那麼其就能夠寫成如圖所示。
    • user_name userName表明數據庫字段和實體類中字段
    • r.id "role.id"此處是經過別名映射的,role是什麼?是聲明在user類中屬性。 enter description here

1.1.2 嵌套結果查詢優缺點

  1. 什麼是?經過了一次查詢把結果映射到了不一樣對象裏。
  2. 好處是什麼?減小了數據庫查詢次數,減小了數據庫的壓力。
  3. 壞處是什麼?要寫複雜的SQL,不容易寫對,因爲要映射到不一樣的對象中,必定程度上增長了服務器的壓力。

1.2 使用resultMap配置一對一映射

1.2.1 具體應用過程

咱們在1.1中使用的方法是直接在select標籤中直接寫後自動映射到實體類,resultType返回類型是一個實體類。還有一種方法是在xml文件中的<resultMap>標籤配置關係,而後再在select的resultType指定返回resultMap。詳細如圖所示: enter description here property是實體類字段名,colum是數據庫字段名。此處resultMap這個標籤是定義了一種映射關係集合,這個集合的類型對應實體類User,因此type指定了一個實體類。一樣咱們在property中仍可使用別名.字段的方法,同1.1。 那麼咱們來看,select語句是怎麼寫的。 enter description here服務器

1.2.2 注意事項

注意的是:去掉了數據庫字段,直接用實體類屬性查詢。至於那個別名問題,暫時尚未想到會出現的場景,只需記住如果使用別名別名和resultMap的column一致mybatis

1.2.3 簡化寫法

首先咱們看這張圖 enter description here 在實際的場景中咱們通常會單獨爲user寫一個映射文件(這個映射文件一般是自動生成工具生成的)裏面,resultMap會寫成如圖所示。這時候,咱們要加一個嵌套查詢的方法,那麼resultMap須要添加一個?這時候咱們要在寫一個,如1.2.1圖,咱們會發現有好多重複的內容。以下圖所示。 enter description here 這個時候,咱們引入一種**繼承(增長extend屬性)**機制。改爲以下圖所示。 enter description here數據庫設計

1.3 使用resultMap的association標籤配置一對一映射

enter description here

  • 在這裏咱們使用了association那麼property中就直接寫屬性名就能夠。
  • 這裏咱們配置了列的前綴,則在Column就能夠省略,可是select就要更改以下。 enter description here
  • 關於associationresultMap屬性應用場景 咱們能夠把角色的關聯單獨拿出來。 enter description here 把這部分單獨放到一個resultMap標籤中,而後直接代用便可。 enter description here
    • 注意事項
    • 同xml可使用ID,不在同一xml用全類名+ID如上圖。

1.4 association標籤查詢(懶加載)

此處咱們假設場景是新的,用戶和博客存在一對一關係,按照數據庫設計的基本原理,咱們再user中設置外鍵指向blog表,對應實體類就是user類中增長Blog類型的blog屬性。工具

1.4.1 與前1.1-1.3三種方式的區別

  • 前三種方式都是複雜查詢
  • 前三種方式都是一次性複雜查詢,映射到不一樣的對象中。
  • 此種方法能夠理解爲簡單查詢,後再根據業務邏輯手動查詢關聯對象,因此出現了急速加載和懶加載的概念。

1.4.2 具體實例

enter description here enter description here association中的屬性介紹fetch

  • select:從查詢ID
  • column:從查詢入參=主查詢字段名,見圖。能夠包含多個用{查詢入參=主查詢字段名,....}
  • fetchType:數據加載方式

查詢語句執行順序ui

  • 執行主查詢->執行從查詢
  • 先查出用戶,而後根據用戶中的blogId去執行從查詢,依次輪流有多少用戶查多少次主查詢->從查詢,主查詢->從查詢,主查詢->從查詢,主查詢->從查詢......

存在問題spa

  • 若是咱們查出來從查詢的數據,即博客,這個數據並無用呢?
  • 若是咱們用戶查詢主查詢用戶有N個,則須要執行N次查詢,每次主查詢會再查詢依次從查詢,則會出現N+1的問題。(其實就是eager加載問題對比JPA)

解決方法設計

  • 增長fetchtype屬性設定爲eager,這樣只有咱們在getBlog()方法纔會執行從查詢。 enter description here 咱們觀察運行結果,會出現從查詢依舊會被執行,而不是再調用getBlog方法才執行。 緣由及解決方法 :在mybatis全局配置中有一個屬性aggressive-lazy-loading: false,這個參數默認爲true,即若是爲true,無論你是否設置lazy都會所有加載。 enter description here
  • 懶加載注意事項 enter description here
  • 當咱們設置好aggressive-lazy-loading: false,咱們若是想進行從查詢呢? enter description here

原文出處:https://www.cnblogs.com/quinntian/p/10763167.html

相關文章
相關標籤/搜索