Mybatis中的resultType和resultMap使用
一、概述
MyBatis中在查詢進行select映射的時候,返回類型可以用resultType,也可以用resultMap,resultType是直接表示返回類型的,而resultMap則是對外部ResultMap的引用,但是resultType跟resultMap不能同時存在。
在MyBatis進行查詢映射時,其實查詢出來的每一個屬性都是放在一個對應(yīng)的Map里面的,其中鍵是屬性名,值則是其對應(yīng)的值。
①當(dāng)提供的返回類型屬性是resultType時
MyBatis會將Map里面的鍵值對取出賦給resultType所指定的對象對應(yīng)的屬性。
所以其實MyBatis的每一個查詢映射的返回類型都是ResultMap,只是當(dāng)提供的返回類型屬性是resultType的時候,MyBatis對自動的給把對應(yīng)的值賦給resultType所指定對象的屬性。
②當(dāng)提供的返回類型是resultMap時
因為Map不能很好表示領(lǐng)域模型,就需要自己再進一步的把它轉(zhuǎn)化為對應(yīng)的對象,這常常在復(fù)雜查詢中很有作用。
二、ResultType
Blog.java public class Blog { private int id; private String title; private String content; private String owner; private List<Comment> comments; }
其所對應(yīng)的數(shù)據(jù)庫表中存儲有id、title、content、owner屬性。
(使用resultType也就意外這屬性名必須和列名一致)
<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會自動創(chuàng)建一個ResultMap對象,然后基于查找出來的屬性名進行鍵值對封裝,然后再看到返回類型是Blog對象,再從ResultMap中取出與Blog對象對應(yīng)的鍵值對進行賦值。
三、ResultMap
當(dāng)返回類型直接是一個ResultMap的時候也是非常有用的,這主要用在進行復(fù)雜聯(lián)合查詢上,因為進行簡單查詢是沒有什么必要的。
先看看一個返回類型為ResultMap的簡單查詢,再看看復(fù)雜查詢的用法。
①簡單查詢的寫法
<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,表示返回結(jié)果映射到哪一個resultMap上,外部resultMap的type屬性表示該resultMap的結(jié)果是一個什么樣的類型,這里是Blog類型,那么MyBatis就會把它當(dāng)作一個Blog對象取出。
resultMap節(jié)點的子節(jié)點id是用于標(biāo)識該對象的id的,而result子節(jié)點則是用于標(biāo)識一些簡單屬性的,其中的Column屬性表示從數(shù)據(jù)庫中查詢的屬性,Property則表示查詢出來的屬性對應(yīng)的值賦給實體對象的哪個屬性。
簡單查詢的resultMap的寫法就是這樣的。
②復(fù)雜查詢
有一個Comment類,其中有一個Blog的引用,表示是對哪個Blog的Comment,那么在查詢Comment的時候把其對應(yīng)的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對象,可以看到在對應(yīng)的resultMap的返回類型是一個Comment對象,其中只有一個association節(jié)點,而沒有像前面說的簡單查詢所對應(yīng)的id、result子節(jié)點,但是其仍會把對應(yīng)的id等屬性賦給Comment對象,這就是前面所說的MyBatis擁有自動封裝功能,只要提供了返回類型,MyBatis會根據(jù)自己的判斷來利用查詢結(jié)果封裝對應(yīng)的對象,所以前面的簡單查詢中,如果不在resultMap中明確的指出id對應(yīng)哪個字段,title對應(yīng)哪個字段,MyBatis也會根據(jù)自身的判斷來幫封裝,MyBatis的自身判斷是把查詢的field或其對應(yīng)的別名與返回對象的屬性進行比較,如果相匹配且類型也相匹配,MyBatis則會對其進行賦值。
在上面對應(yīng)的resultMap中關(guān)聯(lián)了一個blog屬性,其對應(yīng)的java類型為Blog,在上述的寫法中,關(guān)聯(lián)對象是通過子查詢來進行關(guān)聯(lián)的,當(dāng)然也可以直接通過關(guān)聯(lián)查詢來進行關(guān)聯(lián)。
- 上面的association子節(jié)點中,Property屬性表示是resultMap返回類型的哪個關(guān)聯(lián)屬性,對于上面的例子就是Comment管理的blog屬性;
- select表示進行哪個select映射來映射對應(yīng)的關(guān)聯(lián)屬性,即會去請求id為select所對應(yīng)的值的select映射 來查詢出其所關(guān)聯(lián)的屬性對象;
- Column表示當(dāng)前關(guān)聯(lián)對象在id為CommentResult的resultMap中所對應(yīng)的鍵值對,該鍵值對將作為對關(guān)聯(lián)對象子查詢的參數(shù),即將把在selectComment中查詢出來的blog屬性的值作為參數(shù)傳給進行關(guān)聯(lián)對象blog的子查詢selectBlog的參數(shù);
- javaType表示當(dāng)前關(guān)聯(lián)對象在JAVA中是什么類型。
上述介紹的是一對一或一對多的情況下,對一對一方的關(guān)聯(lián)的查詢。
在實際應(yīng)用中還有一個用的比較多的應(yīng)用是通過一對一方查出對應(yīng)的多的一方,在拿出多的一方的時候也同樣要把一對一方關(guān)聯(lián)上:在拿出Blog對象時,就把其對應(yīng)的Comment全部拿出來,在拿出Comment的時候也還是需要把其對應(yīng)的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映射,返回結(jié)果為id為BlogResult的resultMap,id為BlogResult的類型為Blog,其中指定了id的屬性和字段,指定id將對MyBatis內(nèi)部的構(gòu)造作用非常大。
其中關(guān)聯(lián)了一個comments對象,因為一個Blog可以有很多Comment,該comments為一個集合,所以用集合collection進行映射,其中的select還是表示進行哪個子查詢來查詢對應(yīng)的comments,column表示把上述查出來的哪個字段值當(dāng)作參數(shù)傳給子查詢,ofType也是表示返回類型,這里的返回類型是集合內(nèi)部的類型,之所以用ofType而不是用type是MyBatis內(nèi)部為了和關(guān)聯(lián)association進行區(qū)別。
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(); }
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
springboot2如何集成ElasticSearch6.4.3
這篇文章主要介紹了springboot2如何集成ElasticSearch6.4.3問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-07-07使用Spring的攔截器監(jiān)測每個Controller或方法的執(zhí)行時長
這篇文章主要介紹了使用Spring的攔截器監(jiān)測每個Controller或方法的執(zhí)行時長,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-10-10Java實戰(zhàn)之用Swing實現(xiàn)通訊錄管理系統(tǒng)
今天給大家?guī)淼氖荍ava實戰(zhàn)的相關(guān)知識,文章圍繞著Swing實現(xiàn)通訊錄管理系統(tǒng)展開,文中有非常詳細(xì)的代碼示例,需要的朋友可以參考下2021-06-06SpringMVC + servlet3.0 文件上傳的配置和實現(xiàn)代碼
本篇文章主要介紹了SpringMVC + servlet3.0 文件上傳的配置和實現(xiàn)代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下。2017-04-04MybatisPlus中如何調(diào)用Oracle存儲過程
這篇文章主要介紹了MybatisPlus中如何調(diào)用Oracle存儲過程的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-05-05