【MyBatis】MyBatis之association


關聯 association

關聯(association)元素處理“有一個”類型的關系。 比如,在我們的示例中,一個博客有一個用戶。關聯結果映射和其它類型的映射工作方式差不多。 你需要指定目標屬性名以及屬性的javaType(很多時候 MyBatis 可以自己推斷出來),在必要的情況下你還可以設置 JDBC 類型,如果你想覆蓋獲取結果值的過程,還可以設置類型處理器。

關聯的不同之處是,你需要告訴 MyBatis 如何加載關聯。MyBatis 有兩種不同的方式加載關聯:

  • 嵌套 Select 查詢:通過執行另外一個 SQL 映射語句來加載期望的復雜類型。
  • 嵌套結果映射:使用嵌套的結果映射來處理連接結果的重復子集。

首先,先讓我們來看看這個元素的屬性。你將會發現,和普通的結果映射相比,它只在 select 和 resultMap 屬性上有所不同。

屬性 描述
property 映射到列結果的字段或屬性。如果用來匹配的 JavaBean 存在給定名字的屬性,那么它將會被使用。否則 MyBatis 將會尋找給定名稱的字段。 無論是哪一種情形,你都可以使用通常的點式分隔形式進行復雜屬性導航。 比如,你可以這樣映射一些簡單的東西:“username”,或者映射到一些復雜的東西上:“address.street.number”。
javaType 一個 Java 類的完全限定名,或一個類型別名(關於內置的類型別名,可以參考上面的表格)。 如果你映射到一個 JavaBean,MyBatis 通常可以推斷類型。然而,如果你映射到的是 HashMap,那么你應該明確地指定 javaType 來保證行為與期望的相一致。
jdbcType JDBC 類型,所支持的 JDBC 類型參見這個表格之前的“支持的 JDBC 類型”。 只需要在可能執行插入、更新和刪除的且允許空值的列上指定 JDBC 類型。這是 JDBC 的要求而非 MyBatis 的要求。如果你直接面向 JDBC 編程,你需要對可能存在空值的列指定這個類型。
typeHandler 我們在前面討論過默認的類型處理器。使用這個屬性,你可以覆蓋默認的類型處理器。 這個屬性值是一個類型處理器實現類的完全限定名,或者是類型別名。

關聯的嵌套 Select 查詢

屬性 描述
column 數據庫中的列名,或者是列的別名。一般情況下,這和傳遞給 resultSet.getString(columnName) 方法的參數一樣。 注意:在使用復合主鍵的時候,你可以使用 column="{prop1=col1,prop2=col2}" 這樣的語法來指定多個傳遞給嵌套 Select 查詢語句的列名。這會使得 prop1prop2 作為參數對象,被設置為對應嵌套 Select 語句的參數。
select 用於加載復雜類型屬性的映射語句的 ID,它會從 column 屬性指定的列中檢索數據,作為參數傳遞給目標 select 語句。 具體請參考下面的例子。注意:在使用復合主鍵的時候,你可以使用 column="{prop1=col1,prop2=col2}" 這樣的語法來指定多個傳遞給嵌套 Select 查詢語句的列名。這會使得 prop1prop2 作為參數對象,被設置為對應嵌套 Select 語句的參數。
fetchType 可選的。有效值為 lazyeager。 指定屬性后,將在映射中忽略全局配置參數 lazyLoadingEnabled,使用屬性的值。

就是這么簡單。我們有兩個 select 查詢語句:一個用來加載博客(Blog),另外一個用來加載作者(Author),而且博客的結果映射描述了應該使用 selectAuthor 語句加載它的 author 屬性。

其它所有的屬性將會被自動加載,只要它們的列名和屬性名相匹配。

這種方式雖然很簡單,但在大型數據集或大型數據表上表現不佳。這個問題被稱為“N+1 查詢問題”。 概括地講,N+1 查詢問題是這樣子的:

  • 你執行了一個單獨的 SQL 語句來獲取結果的一個列表(就是“+1”)。
  • 對列表返回的每條記錄,你執行一個 select 查詢語句來為每條記錄加載詳細信息(就是“N”)。

這個問題會導致成百上千的 SQL 語句被執行。有時候,我們不希望產生這樣的后果。

好消息是,MyBatis 能夠對這樣的查詢進行延遲加載,因此可以將大量語句同時運行的開銷分散開來。 然而,如果你加載記錄列表之后立刻就遍歷列表以獲取嵌套的數據,就會觸發所有的延遲加載查詢,性能可能會變得很糟糕。

<resultMap  id ="bookMap2"         type="Book">
		<id     property="id"          column="id" />
		<result property="bookName"    column="book_name" />
		<result property="authorId"    column="author_id" />
		<association property="author" javaType="Author" column="author_id"  
			select="com.wcw.mapper.AuthorMapper.selectById">			
		</association>
</resultMap>
<select id ="selectBookDetail2" resultMap="bookMap2">
		select * from book where id = #{bookId}
</select>

<resultMap id = "authorMap1" type="Author">
		<id property="id" column="id"/>
		<result property="username" column="username"/>
		<result property="password" column="password	"/>
		<result property="email"    column="email"/>
		<result property="bio"      column="bio"/>
</resultMap>
<select id="selectById" resultMap="authorMap1">
		select 
			a.id,a.username,a.password,email,a.bio
		from author a where a.id = #{id}
</select>

關聯的嵌套結果映射

屬性 描述
resultMap 結果映射的 ID,可以將此關聯的嵌套結果集映射到一個合適的對象樹中。 它可以作為使用額外 select 語句的替代方案。它可以將多表連接操作的結果映射成一個單一的 ResultSet。這樣的 ResultSet 有部分數據是重復的。 為了將結果集正確地映射到嵌套的對象樹中, MyBatis 允許你“串聯”結果映射,以便解決嵌套結果集的問題。使用嵌套結果映射的一個例子在表格以后。
columnPrefix 當連接多個表時,你可能會不得不使用列別名來避免在 ResultSet 中產生重復的列名。指定 columnPrefix 列名前綴允許你將帶有這些前綴的列映射到一個外部的結果映射中。 詳細說明請參考后面的例子。
notNullColumn 默認情況下,在至少一個被映射到屬性的列不為空時,子對象才會被創建。 你可以在這個屬性上指定非空的列來改變默認行為,指定后,Mybatis 將只在這些列非空時才創建一個子對象。可以使用逗號分隔來指定多個列。默認值:未設置(unset)。
autoMapping 如果設置這個屬性,MyBatis 將會為本結果映射開啟或者關閉自動映射。 這個屬性會覆蓋全局的屬性 autoMappingBehavior。注意,本屬性對外部的結果映射無效,所以不能搭配 selectresultMap 元素使用。默認值:未設置(unset)。
<resultMap id ="bookMap" type="Book">
    <id     property="id"          column="id" />
    <result property="bookName"    column="book_name" />
    <association property="author" javaType="Author" columnPrefix="author_" 
                 resultMap="com.wcw.mapper.AuthorMapper.authorMap1">			
    </association>
</resultMap>
<select id="selectBookDetail" resultMap="bookMap" >
		select b.id as id,
		b.book_name,
		b.author_id,
		a.username as author_username,
		a.password as author_password,
		a.email    as author_email,
		a.bio      as author_bio
		from book b inner join author a on b.author_id = a.id
		where b.id = #{bookId}
</select>

代碼地址:https://gitee.com/firefish/mybatis_study

摘抄:https://mybatis.org/mybatis-3/zh/sqlmap-xml.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM