Mybatis--resultType和resultMap

1、概述
MyBatis中在查詢進行select映射的時候,返回類型能夠用resultType,也能夠用resultMap,resultType是直接表示返回類型的,而resultMap則是對外部ResultMap的引用,可是resultType跟resultMap不能同時存在。
在MyBatis進行查詢映射時,其實查詢出來的每個屬性都是放在一個對應的Map裏面的,其中鍵是屬性名,值則是其對應的值。
①當提供的返回類型屬性是resultType時,MyBatis會將Map裏面的鍵值對取出賦給resultType所指定的對象對應的屬性。因此其實MyBatis的每個查詢映射的返回類型都是ResultMap,只是當提供的返回類型屬性是resultType的時候,MyBatis對自動的給把對應的值賦給resultType所指定對象的屬性。
②當提供的返回類型是resultMap時,由於Map不能很好表示領域模型,就須要本身再進一步的把它轉化爲對應的對象,這經常在複雜查詢中頗有做用。

2、ResultType
Blog.java
public class Blog {
private int id;
private String title;
private String content;
private String owner;
private List<Comment> comments;
}
其所對應的數據庫表中存儲有id、title、Content、Owner屬性。
<typeAlias alias="Blog" type="com.tiantian.mybatis.model.Blog"/>
<select id="selectBlog" parameterType="int" resultType="Blog">
select * from t_blog where id = #{id}
</select>
MyBatis會自動建立一個ResultMap對象,而後基於查找出來的屬性名進行鍵值對封裝,而後再看到返回類型是Blog對象,再從ResultMap中取出與Blog對象對應的鍵值對進行賦值。


3、ResultMap
當返回類型直接是一個ResultMap的時候也是很是有用的,這主要用在進行復雜聯合查詢上,由於進行簡單查詢是沒有什麼必要的。先看看一個返回類型爲ResultMap的簡單查詢,再看看複雜查詢的用法。

①簡單查詢的寫法
<resultMap type="Blog" id="BlogResult">
<id column="id" property="id"/>
<result column="title" property="title"/>
<result column="content" property="content"/>
<result column="owner" property="owner"/>
</resultMap>
<select id="selectBlog" parameterType="int" resultMap="BlogResult">
select * from t_blog where id = #{id}
</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屬性。
public class Comment {
private int id;
private String content;
private Date commentDate = new Date();
private Blog blog;
}
<!--來自CommentMapper.xml文件-->
<resultMap type="Comment" id="CommentResult">
<association property="blog" select="selectBlog" column="blog" javaType="Blog"/>
</resultMap>

<select id="selectComment" parameterType="int" resultMap="CommentResult">
select * from t_Comment where id = #{id}
</select>

<select id="selectBlog" parameterType="int" resultType="Blog">
select * from t_Blog where id = #{id}
</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中經過一次請求就拿出來的。

<!-- 來自BlogMapper.xml文件 -->
<resultMap type="Blog" id="BlogResult">
<id column="id" property="id"/>
<collection property="comments" select="selectCommentsByBlog" column="id" ofType="Comment"></collection>
</resultMap>

<resultMap type="Comment" id="CommentResult">
<association property="blog" javaType="Blog" column="blog" select="selectBlog"/>
</resultMap>

<select id="selectBlog" parameterType="int" resultMap="BlogResult">
select * from t_blog where id = #{id}
  </select>

  <select id="selectCommentsByBlog" parameterType="int" resultMap="CommentResult">
  select * from t_Comment where blog = #{blogId}
  </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進行區別。 

public void selectCommentsByBlogTest() {
SqlSession session = Util.getSqlSessionFactory().openSession();
CommentMapper commentMapper = session.getMapper(CommentMapper.class);
List<Comment> comments = commentMapper.selectCommentsByBlog(6);
for (Comment comment : comments)
System.out.println(comment);
session.close();
}

public void testSelectOne() {
SqlSession session = Util.getSqlSessionFactory().openSession();
BlogMapper blogMapper = session.getMapper(BlogMapper.class);
Blog blog = blogMapper.selectBlog(6);
List<Comment> comments = blog.getComments();
if (comments != null) {
for (Comment comment : comments)
System.out.println(comment);
}
session.close();
}java

相關文章
相關標籤/搜索