首页 > 其他分享 >MyBatis的ResultMap使用方法,对象关联写法

MyBatis的ResultMap使用方法,对象关联写法

时间:2024-07-12 19:23:13浏览次数:14  
标签:resultMap 查询 Blog ResultMap MyBatis 写法 id 属性

 

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.   
  3. public class Blog {  
  4.   
  5.     private int id;  
  6.   
  7.     private String title;  
  8.   
  9.     private String content;  
  10.   
  11.     private String owner;  
  12.       
  13.     private List<Comment> comments;  
  14.   
  15.    // getter setter ...
  16. }  

 

其所对应的数据库表中存储有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.   
  3. public class Comment {  
  4.   
  5.     private int id;  
  6.       
  7.     private String content;  
  8.       
  9.     private Date commentDate = new Date();  
  10.       
  11.     private Blog blog;  
  12.   
  13.     // getter setter ...
  14. }  
 

 

其写法是这样的

 

Xml代码  收藏代码
  1. <!--来自CommentMapper.xml文件    -->  
  2.     <resultMap type="Comment" id="CommentResult">  
  3.         <association property="blog" select="selectBlog" column="blog" javaType="Blog"/>  
  4.     </resultMap>  
  5.       
  6.     <select id="selectComment" parameterType="int" resultMap="CommentResult">  
  7.         select * from t_Comment where id = #{id}  
  8.     </select>  
  9.       
  10.     <select id="selectBlog" parameterType="int" resultType="Blog">  
  11.         select * from t_Blog where id = #{id}  
  12.     </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.   
  7.     <resultMap type="Comment" id="CommentResult">  
  8.         <association property="blog" javaType="Blog" column="blog" select="selectBlog"/>  
  9.     </resultMap>  
  10.   
  11.     <select id="selectBlog" parameterType="int" resultMap="BlogResult">  
  12.         select * from t_blog where id = #{id}  
  13.     </select>  
  14.   
  15. <!--  通过Blog来查找Comment   -->  
  16.     <select id="selectCommentsByBlog" parameterType="int" resultMap="CommentResult">  
  17.         select * from t_Comment where blog = #{blogId}  
  18.     </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.  */  
  14. @Test  
  15. public void testSelectOne() {  
  16.     SqlSession session = Util.getSqlSessionFactory().openSession();  
  17.     BlogMapper blogMapper = session.getMapper(BlogMapper.class);  
  18.     Blog blog = blogMapper.selectBlog(6);  
  19.     List<Comment> comments = blog.getComments();  
  20.     if (comments != null) {  
  21.         System.out.println("--------------Comments Size------------" + comments.size());  
  22.         for (Comment comment : comments)  
  23.             System.out.println(comment);  
  24.     }  
  25.     session.close();  
    http://haohaoxuexi.iteye.com/blog/1337009  
0

标签:resultMap,查询,Blog,ResultMap,MyBatis,写法,id,属性
From: https://www.cnblogs.com/joe-tang/p/7145734.html

相关文章

  • 自定义ResultMap中的id 和result的区别
    <resultMapid="CashInvoiceMap"type="com.dfire.soa.invoice.bo.Invoice">  <idcolumn="id"property="id"/>  <resultcolumn="order_id"property="orderId"/>  <resultco......
  • resultMap之collection聚集
     聚集元素用来处理“一对多”的关系。需要指定映射的Java实体类的属性,属性的javaType(一般为ArrayList);列表中对象的类型ofType(Java实体类);对应的数据库表的列名称;不同情况需要告诉MyBatis如何加载一个聚集。MyBatis可以用两种方式加载:1.select:执行一个其它映射的SQL语句返回......
  • MyBatis用嵌套ResultMap实现一对多映射
    背景我们知道,MyBatis可以很方便地把SQLselect出来的数据直接映射为对象的属性,把对象取出来。但是,有些对象的属性是集合类型,集合里保存的是数个其他类型的对象。如何用MyBatis把它取出来呢?例子以以下这个应用场景为例:一个教师对应多个课程。数据结构如下:publicclassCour......
  • Mybatis模糊查询MySQL中记录的的常用三种方法
    mybatis的模糊查询功能使用的很广泛,以MySQL数据库为例(不同的数据库,有些可能不支持) 常用的模糊查询有三种方法:直接使用%拼接字符串,如 '%'#{name}'%' 或 "%"#{name}"%",单引号或双引号都可以。(或者  '%${vendorId}%' )<iftest="vendorId!=nullandvendorId!=......
  • Mybatis association与collection的区别
    mybatisassociation与collection的区别:一、一对一 association通常用来映射一对一的关系1<resultMaptype="cn.itcast.mybatis.po.Orders"id="OrdersUserResultMap">23<!--配置映射的订单信息-->4<idcolumn="id"prope......
  • mybatis动态Sql(where)和sql片段
    sql片段的定义;1<sqlid="condition">2<iftest="entity.dicttype!=null">and`dicttype`=#{entity.dicttype}</if>3<iftest="entity.dictname!=nullandentity.dictname!=''......
  • 【Springboot】玩转复杂单元测试启动类-只测试数据访问层(JPA+Mybatis) 和服务层 以及
    上一篇文章写了一个最复杂的SpringBootTest启动类,定制化程序奇高,然而有时候仅测试JPA是不够的。启动类需求:测试SpringDataJPA测试Mybatis从容器中获得ObjectMapper测试单独的Service使用TestNG或者使用Junit阻止Dubbo、Kafka、ElasticSearch等中间件启动使用appl......
  • then catch 简易写法
    为了捕获上一步then中的promise结果,必须在上一步return;关闭遮罩层,放在finally中,即无论成功或失败都要执行;archiveAction(actionType,row){constids=row&&row.id?row.id:this.ids;consttip=row&&row.id?`“${row.projectName}”`:......
  • Mybatis-Plus最优化持久层开发
    Mybatis-plus:最优化持久层开发一:Mybatis-plus快速入门:1.1:简介:Mybatis-plus(简称MP)是一个Mybatis的增强工具,在mybatis的基础上只做增强不做改变;提高效率;自动生成单表的CRUD功能;提供了丰富的条件拼接方式;全自动ORM类型持久层框架;(不仅提供数据库操作的方法,还会提供sql语句......
  • mybatis中的标签
    在MyBatis中,除了基本的SQL映射功能外,还有许多用于动态SQL构建的标签。这些标签允许我们根据不同的条件和需求构建复杂的SQL语句。主要的动态SQL标签包括<if>,<choose>,<when>,<otherwise>,<trim>,<set>,<foreach>,以及<bind>等。下面详细介绍这些标签的用途和用法。......