1. 程式人生 > >MyBatis的ResultMap使用方法,物件關聯寫法

MyBatis的ResultMap使用方法,物件關聯寫法

MyBatis中在查詢進行select對映的時候,返回型別可以用resultType,也可以用resultMap,resultType是直接表示返回型別的,而resultMap則是對外部ResultMap的引用,但是resultType跟resultMap不能同時存在。在MyBatis進行查詢對映的時候,其實查詢出來的每一個屬性都是放在一個對應的Map裡面的,其中鍵是屬性名,值則是其對應的值。當提供的返回型別屬性是resultType的時候,MyBatis會將Map裡面的鍵值對取出賦給resultType所指定的物件對應的屬性。所以其實MyBatis的每一個查詢對映的返回型別都是ResultMap,只是當我們提供的返回型別屬性是resultType的時候,MyBatis對自動的給我們把對應的值賦給resultType所指定物件的屬性,而當我們提供的返回型別是resultMap的時候,因為Map不能很好表示領域模型,我們就需要自己再進一步的把它轉化為對應的物件,這常常在複雜查詢中很有作用。

有這樣一個Blog.java檔案

Java程式碼  收藏程式碼
  1. import java.util.List;  
  2. public class Blog {  
  3.     private int id;  
  4.     private String title;  
  5.     private String content;  
  6.     private String owner;  
  7.     private List<Comment> comments;  
  8.    // getter setter ...
  9. }  

其所對應的資料庫表中儲存有id,title,Content,Owner屬性,那麼當我們進行下面這樣一個查詢對映的時候

Xml程式碼  收藏程式碼
  1. <typeAlias alias="Blog" type="com.tiantian.mybatis.model.Blog"/><!--來自MyBatis的配置檔案mybatis_config.xml-->  
  2. <select id="selectBlog" parameterType="int" resultType="Blog">  
  3.         select * from t_blog where id = #{id}  
  4. </select><!--來自SQL對映檔案BlogMapper.xml-->
      

 MyBatis會自動建立一個ResultMap物件,然後基於查找出來的屬性名進行鍵值對封裝,然後再看到返回型別是Blog物件,再從ResultMap中取出與Blog物件對應的鍵值對進行賦值。

當返回型別直接是一個ResultMap的時候也是非常有用的,這主要用在進行復雜聯合查詢上,因為進行簡單查詢是沒有什麼必要的。我們先看看一個返回型別為ResultMap的簡單查詢,再看看複雜查詢的用法。

簡單查詢的寫法

Xml程式碼  收藏程式碼
  1. <resultMap type="Blog" id="BlogResult">  
  2.         <id column="id" property="id"/>  
  3.         <result column="title" property="title"/>  
  4.         <result column="content" property="content"/>  
  5.         <result column="owner" property="owner"/>  
  6.     </resultMap>  
  7.     <select id="selectBlog" parameterType="int" resultMap="BlogResult">  
  8.         select * from t_blog where id = #{id}  
  9.     </select>  

 select對映中resultMap的值是一個外部resultMap的id,表示返回結果對映到哪一個resultMap上,外部resultMap的type屬性表示該resultMap的結果是一個什麼樣的型別,這裡是Blog型別,那麼MyBatis就會把它當作一個Blog物件取出。resultMap節點的子節點id是用於標識該物件的id的,而result子節點則是用於標識一些簡單屬性的,其中的Column屬性表示從資料庫中查詢的屬性,Property則表示查詢出來的屬性對應的值賦給實體物件的哪個屬性。簡單查詢的resultMap的寫法就是這樣的。接下來看一個複雜一點的查詢。

有一個Comment類,其中有一個Blog的引用,表示是對哪個Blog的Comment,那麼我們在查詢Comment的時候把其對應的Blog也要查出來賦給其blog屬性。

Java程式碼  收藏程式碼
  1. import java.util.Date;  
  2. public class Comment {  
  3.     private int id;  
  4.     private String content;  
  5.     private Date commentDate = new Date();  
  6.     private Blog blog;  
  7.     // getter setter ...
  8. }  

其寫法是這樣的

Xml程式碼  收藏程式碼
  1. <!--來自CommentMapper.xml檔案    -->  
  2.     <resultMap type="Comment" id="CommentResult">  
  3.         <association property="blog" select="selectBlog" column="blog" javaType="Blog"/>  
  4.     </resultMap>  
  5.     <select id="selectComment" parameterType="int" resultMap="CommentResult">  
  6.         select * from t_Comment where id = #{id}  
  7.     </select>  
  8.     <select id="selectBlog" parameterType="int" resultType="Blog">  
  9.         select * from t_Blog where id = #{id}  
  10.     </select>  

其訪問情況是這樣的,先是請求id為selectComment的select對映,然後得到一個id為CommentResult的ResultMap物件,我們可以看到在對應的resultMap的返回型別是一個Comment物件,其中只有一個association節點,而沒有像前面說的簡單查詢所對應的id,result子節點,但是其仍會把對應的id等屬性賦給Comment物件,這就是前面所說的MyBatis擁有自動封裝功能,只要你提供了返回型別,MyBatis會根據自己的判斷來利用查詢結果封裝對應的物件,所以前面的簡單查詢中,如果你不在resultMap中明確的指出id對應哪個欄位,title對應哪個欄位,MyBatis也會根據自身的判斷來幫你封裝,MyBatis的自身判斷是把查詢的field或其對應的別名與返回物件的屬性進行比較,如果相匹配且型別也相匹配,MyBatis則會對其進行賦值。在上面對應的resultMap中關聯了一個blog屬性,其對應的JAVA型別為Blog,在上述的寫法中,關聯物件是通過子查詢來進行關聯的,當然也可以直接通過關聯查詢來進行關聯。上面的association子節點中,Property屬性表示是resultMap返回型別的哪個關聯屬性,對於上面的例子就是Comment管理的blog屬性;select表示進行哪個select對映來對映對應的關聯屬性,即會去請求id為select所對應的值的select對映 來查詢出其所關聯的屬性物件;Column表示當前關聯物件在id為CommentResult的resultMap中所對應的鍵值對,該鍵值對將作為對關聯物件子查詢的引數,即將把在selectComment中查詢出來的blog屬性的值作為引數傳給進行關聯物件blog的子查詢selectBlog的引數;javaType表示當前關聯物件在JAVA中是什麼型別。

上述介紹的是一對一或一對多的情況下,對一的一方的關聯的查詢。在實際應用中還有一個用的比較多的應用是通過一的一方查出對應的多的一方,在拿出多的一方的時候也同樣要把一的一方關聯上,即在上述例子中,在拿出Blog物件的時候,就把其對應的Comment全部拿出來,在拿出Comment的時候也還是需要把其對應的Blog拿出來,這是在JAVA中通過一次請求就拿出來的。寫法如下:

Xml程式碼  收藏程式碼
  1. <!-- 來自BlogMapper.xml檔案 -->  
  2.     <resultMap type="Blog" id="BlogResult">  
  3.         <id column="id" property="id"/>  
  4.         <collection property="comments" select="selectCommentsByBlog" column="id" ofType="Comment"></collection>  
  5.     </resultMap>  
  6.     <resultMap type="Comment" id="CommentResult">  
  7.         <association property="blog" javaType="Blog" column="blog" select="selectBlog"/>  
  8.     </resultMap>  
  9.     <select id="selectBlog" parameterType="int" resultMap="BlogResult">  
  10.         select * from t_blog where id = #{id}  
  11.     </select>  
  12. <!--  通過Blog來查詢Comment   -->  
  13.     <select id="selectCommentsByBlog" parameterType="int" resultMap="CommentResult">  
  14.         select * from t_Comment where blog = #{blogId}  
  15.     </select>  

上述請求的入口是id為selectBlog的select對映,返回結果為id為BlogResult的resultMap,id為BlogResult的型別為Blog,其中指定了id的屬性和欄位,指定id將對MyBatis內部的構造作用非常大。其中關聯了一個comments物件,因為一個Blog可以有很多Comment,該comments為一個集合,所以用集合collection進行對映,其中的select還是表示進行哪個子查詢來查詢對應的comments,column表示把上述查出來的哪個欄位值當作引數傳給子查詢,ofType也是表示返回型別,這裡的返回型別是集合內部的型別,之所以用ofType而不是用type是MyBatis內部為了和關聯association進行區別。 

測試程式碼:

Java程式碼  收藏程式碼
  1. @Test  
  2. public void selectCommentsByBlogTest() {  
  3.     SqlSession session = Util.getSqlSessionFactory().openSession();  
  4.     CommentMapper commentMapper = session.getMapper(CommentMapper.class);  
  5.     List<Comment> comments = commentMapper.selectCommentsByBlog(6);  
  6.     for (Comment comment : comments)  
  7.         System.out.println(comment);  
  8.     session.close();  
  9. }  
  10. /** 
  11.  * 查詢單條記錄 
  12.  */  
  13. @Test  
  14. public void testSelectOne() {  
  15.     SqlSession session = Util.getSqlSessionFactory().openSession();  
  16.     BlogMapper blogMapper = session.getMapper(BlogMapper.class);  
  17.     Blog blog = blogMapper.selectBlog(6);  
  18.     List<Comment> comments = blog.getComments();  
  19.     if (comments != null) {  
  20.         System.out.println("--------------Comments Size------------" + comments.size());  
  21.         for (Comment comment : comments)  
  22.             System.out.println(comment);  
  23.     }  
  24.     session.close();  
http://haohaoxuexi.iteye.com/blog/1337009

相關推薦

MyBatis的ResultMap使用方法物件關聯寫法

MyBatis中在查詢進行select對映的時候,返回型別可以用resultType,也可以用resultMap,resultType是直接表示返回型別的,而resultMap則是對外部ResultMap的引用,但是resultType跟resultMap不能同時存在。

屬性方法物件

 抽象:抽出像的部分,抽出共同的部分 通過抽象得到類,以類為模板產生物件 物件可以通過兩種方式得到:例項化和宣告 屬性:類的特點(學生的id、姓名等) 光有屬性沒有方法叫做結構體 方法:類的功能(學生能學習,玩等) package com.learn; /**

Java 類方法物件引數傳參

遇到一個非常鬱悶的問題。 寫了一個工具類,方法都是靜態方法。方法中的引數為物件,我以為把當前物件傳入,對物件進行的操作是地址操作。誰知道,並不是。是值,類的靜態方法接收的物件會自動克隆一個副本來做操作。所做的操作都是對副本進行操作,而不是真正傳進來的物件。切記了

JS函式物件例項方法物件方法理解

var _s = function(){ var name = 'lisa';                 //內部屬性 var age = 10; var sen = function(){ console.log("函式_s") ;  //函式內部屬性,作用

物件建立方法物件的記憶體分配物件的訪問定位

物件建立方法:   JVM遇到一條new指令時,首先檢查這個指令的引數是否能在常量池中定位到一個類的符號引用,並且檢查這個符號引用代表的類是否已被載入、連線和初始化過。 如果沒有,那必須先執行相應的類的載入過程。 物件的記憶體分配:   物件所需記憶體的大小在類載入完成後便完全確定(物件記憶體佈局),為物件

JNI字串陣列欄位和方法物件引用異常處理多執行緒記憶體回收等

  JNI中字串,陣列,欄位和方法,區域性引用和全域性引用,異常處理,多執行緒等核心內容。-- finalize的作用: 1.finalize()是Object的protected方法,子類可以覆蓋該方法以實現資源清理工作,GC在回收物件之前呼叫該方法。 2.finalize

淺談javascript之事件、函式、方法物件 各代表何含義通俗解釋及其之間的關聯與區別

簡單來說: 在javascript中,所有的事件都是通過函式來執行的,函式本身即是動作(針對事件來說),也是方法(針對物件來說)!物件是指的誰觸發了事件,繫結事件的主謀。 【事件】事件就如神經開關,刺

mysql下分組取關聯表指定提示方法類似於mssql中的cross apply

nbsp cts ont font ack you 方法 sta lease 轉至:https://stackoverflow.com/questions/12113699/get-top-n-records-for-each-group-of-grouped-result

Python面向物件操作使用方法10年經驗教你!

  在Python中,所有資料型別都可以視為物件,當然也可以自定義物件。自定義的物件資料型別就是面向物件中的類(Class)的概念。 我們以一個例子來說明面向過程和麵向物件在程式流程上的不同之處。 假設我們要處理學生的成績表,為了表示一個學生的成績,面向過程的程式可以用一個dict

SpringBoot專案開發(二十三):Ajax Post資料到控制器方法引數自動轉換為物件

往往有這麼個需求,在新增使用者時,頁面以 ajax 方式把 user 物件資料提交到後臺控制器上, 控制器方法中的引數以物件形式進行接收,這時就需要把json字串自動轉換為物件 在SpringBoot或SpringMvc中,有@ResponseBody 、@RequestBody 兩

js獲取物件屬性的兩種方法object.屬性名[‘屬性名’ ]

1、通過點的方式 2、通過括號的方式 例: <input type="text" value="hello" id="text"/> var oText = document.getElementById("text") (1)通過點的方式   oText.pr

物件的列舉(2)- in與 instanceof以及區分陣列物件方法

2.in                 * __proto__ : { lastName : "deng", //__pro

JavaScript中prototype(原型)給字串物件新增一個toCharArray的方法reverse(翻轉)的 方法

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http:/

空指標異常(空物件呼叫成員屬性或者是成員方法增強for迴圈自動拆箱)

什麼時候會出現空指標異常? 呼叫一個空物件(null)的成員屬性或者是成員方法的時候回出現空指標異常 演示: package hello_java; public class Test { public static void main(String[] ar

String類重寫的equals方法比較的是字元序列比較物件不是字串時注意使用toString()方法

今天幫同事debug,問題描述:判斷相應條件之後,沒有按照預想的結果接入if語句中; 其程式碼如下: Map<String, Object> alarmByAlarmNum = alarmMapper.getAlarmByDeviceNumber(deviceNumber);

$.browser.msie 為空或不是物件問題的多種解決方法jquery高版本廢棄低版本api屬性不相容問題

複製文章地址(原文):點選開啟連結 '$.browser.msie' 為空或不是物件,這個是jQuery錯誤出現這個錯誤,是因為升級了jQuery版本,從1.9以前升級到1.9以後,因為$.browser.msie在1.9以後的jQuery中不存在了,所以報錯。 jQuery 1.9 移除了

通過反射建立私有化類的物件呼叫類的私有方法改變私有屬性

首先建立一個類 public class ReflectDemo { private int m=0; //私有屬性 private ReflectDemo(){ //私有無參建構函式 } public ReflectDemo(int aa

結合多個例項深入理解js的深拷貝和淺拷貝多種方法實現物件的深拷貝

親們為什麼要研究深拷貝和淺拷貝呢,因為我們專案開發中有許多情況需要拷貝一個數組抑或是物件,但是單純的靠=“賦值”並不會解決所有問題,如果遇到引用型別的物件改變新賦值的物件會造成原始物件也發生同樣改變,而要去除影響就必須用到深拷貝,深拷貝,對於引用物件需要進行深拷貝才會去除影響。如果是值型別直接“=”

面向物件之(非)繫結方法反射isinstance與issubclass

isinstance(obj,cls)和issubclass(sub,super) isinstance(obj,cls)檢查是否obj是否是類 cls 的物件 class Foo(object): pass obj = Foo() isinstance(obj, Foo)

List集合練習題 完成getAllDog 方法從一個Animal集合中挑選出所有的Dog物件並把這些物件 放在一個Dog 集合中返回。

package cn.sc.test; import java.util.ArrayList; import java.util.List; public class TestAnimal { public static void main(String[] args) { List