`

【Mybatis】表关联和resultMap的使用

阅读更多

基础部分可以查看我的另一篇博客http://haohaoxuexi.iteye.com/blog/1333271

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.     public int getId() {   
  16.         return id;   
  17.     }   
  18.   
  19.     public void setId(int id) {   
  20.         this.id = id;   
  21.     }   
  22.   
  23.     public String getTitle() {   
  24.         return title;   
  25.     }   
  26.   
  27.     public void setTitle(String title) {   
  28.         this.title = title;   
  29.     }   
  30.   
  31.     public String getContent() {   
  32.         return content;   
  33.     }   
  34.   
  35.     public void setContent(String content) {   
  36.         this.content = content;   
  37.     }   
  38.   
  39.     public String getOwner() {   
  40.         return owner;   
  41.     }   
  42.   
  43.     public void setOwner(String owner) {   
  44.         this.owner = owner;   
  45.     }   
  46.        
  47.     public List<Comment> getComments() {   
  48.         return comments;   
  49.     }   
  50.        
  51.     public void setComments(List<Comment> comments) {   
  52.         this.comments = comments;   
  53.     }   
  54.   
  55.     @Override  
  56.     public String toString() {   
  57.         return " ----------------博客-----------------\n id: " + id + "\n title: " + title + "\n content: " + content   
  58.                 + "\n owner: " + owner;   
  59.     }   
  60.   
  61. }  
  1.    
 

其所对应的数据库表中存储有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-->  
    1.    
     

 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>  
    1.    
     

 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.     public int getId() {   
  14.         return id;   
  15.     }   
  16.   
  17.     public void setId(int id) {   
  18.         this.id = id;   
  19.     }   
  20.   
  21.     public String getContent() {   
  22.         return content;   
  23.     }   
  24.   
  25.     public void setContent(String content) {   
  26.         this.content = content;   
  27.     }   
  28.   
  29.     public Date getCommentDate() {   
  30.         return commentDate;   
  31.     }   
  32.   
  33.     public void setCommentDate(Date commentDate) {   
  34.         this.commentDate = commentDate;   
  35.     }   
  36.   
  37.     public Blog getBlog() {   
  38.         return blog;   
  39.     }   
  40.   
  41.     public void setBlog(Blog blog) {   
  42.         this.blog = blog;   
  43.     }   
  44.        
  45.     public String toString() {   
  46.         return blog + "\n ----------------评论-----------------\n id: " + id + "\n content: " + content + "\n commentDate: " + commentDate;   
  47.     }   
  48.        
  49. }  
  1.    
 
 

其写法是这样的

 

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>  
    1.    
     

上述请求的入口是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();   
  26. }  
分享到:
评论

相关推荐

    MyBatis源码:原来 resultMap解析完是这样.docx

    MyBatis是一个流行的持久层框架,它允许开发者将SQL、XML或注解配置以及Java...通过深入了解`ResultMapping`和`ResultMap`类的内部机制,开发者能够更好地定制和控制MyBatis的行为,以适应不同的数据模型和业务需求。

    MyBatis_sql-resultMap-缓存

    总的来说,`resultMap`和缓存机制是MyBatis提高开发效率和系统性能的关键要素。理解并合理运用它们,可以有效地提升你的项目开发体验和应用性能。在实际开发中,根据业务需求,灵活配置和管理`resultMap`,以及适当...

    mybatis自关联查询

    对于一对多的自关联查询,我们可以使用 `&lt;resultMap&gt;` 来定义映射规则,并通过 `&lt;association&gt;` 标签来处理自关联的字段。以下是一个示例: ```xml &lt;resultMap id="categoryResultMap" type=...

    Springboot中mybatis表关联映射关系(一对一)

    Springboot 中 MyBatis 表关联映射关系(一对一) 在 Springboot 中,MyBatis 提供了强大的表关联映射关系机制,可以实现一对一、多对一、多对多等各种关联关系。在本文中,我们将详细介绍 Springboot 中 MyBatis ...

    Mybatis高级-resultMap之collection聚集

    ### Mybatis高级-resultMap之collection聚集 ...通过以上步骤,我们成功地实现了在MyBatis中使用`collection`元素来处理一对多的数据关联。这种方式不仅可以简化代码,还能提高程序的可读性和可维护性。

    mybatis-demo4-resultMap手动映射.zip

    在`mybatis-demo4-resultMap手动映射.zip`这个示例中,我们可能会看到如何定义一个ResultMap,如何处理一对一和一对多的关系,以及如何使用自定义类型处理器。通过对这个示例的学习,你可以更好地理解ResultMap在...

    基于java的企业级应用开发:MyBatis的关联映射.ppt

    总的来说,MyBatis的关联映射是实现Java对象与数据库表关联关系的重要手段,通过合理使用`&lt;association&gt;`元素和延迟加载机制,可以在保证开发灵活性的同时,有效提升应用程序的性能。学习并掌握这些知识点对于进行...

    MyBatis的关联映射

    **MyBatis关联映射详解** 在Java开发中,MyBatis作为一个优秀的持久层框架,提供了灵活的数据映射功能,使得数据库操作变得简单而高效。其中,关联映射是MyBatis中的一个重要特性,用于处理数据库中复杂的关系,如...

    MyBatis关联映射代码

    2. 嵌套结果:当主表和子表的数据在同一查询结果集中时,MyBatis会根据ResultMap来解析并关联这些数据。这种方式适用于主表和子表数据在同一个SELECT语句中返回的情况。 以下是一个简单的例子,展示了如何在MyBatis...

    mybatis3--4.resultMap高级映射

    在MyBatis中,ResultMap是核心配置之一,它提供了高级映射功能,使得我们可以更加灵活地处理数据库查询结果到Java对象的转换。...熟练掌握ResultMap的使用,能显著提升MyBatis的开发效率和代码质量。

    Mybatis resultMap

    ResultMap的设计旨在提高灵活性,解决对象与数据库表之间的映射问题,尤其是在面对一对多、多对一或自关联等复杂关系时。 ResultMap 的工作原理是通过定义字段到对象属性的映射规则,使得Mybatis能够将SQL查询的...

    Mybatis实现多表联合查询和批量插入

    首先,需要在mybatis-cfg.xml文件中配置 Employees 表的两个元素作为外键关联表 organizations 和表 positions。 ```xml ``` 2. Entity 中 employees 属性作为外键配置 在 Entity 中,需要配置 ...

    mybatis 关联查询完整代码

    本篇文章将详细探讨MyBatis在关联查询中的一对一和一对多关系映射,以及如何通过ResultMap配置来实现这些复杂的查询。 在数据库设计中,一对一和一对多的关系非常常见。一对一关系通常出现在两个表之间,其中一个表...

    MyBatis3关联关系

    总的来说,MyBatis 的关联关系映射提供了一种灵活的方式来处理数据库中的复杂关系,通过 ResultMap 和 SQL 查询的结合,可以有效地控制数据加载的方式,提高应用性能。无论是简单的一对一、一对多映射,还是涉及多个...

    根据MyBatis的ResultMap生成增删改sql

    ResultMap是MyBatis的核心组件之一,用于解决对象关系映射的复杂性,比如一对一、一对多、多对多等关联关系的处理。 首先,ResultMap的概念。ResultMap是MyBatis中定义的一种映射规则,用于解析查询结果并将其映射...

    实现Mybatis框架中一对多关联映射的查询操作。

    在这个例子中,User表(用户表)和Order_form表(订单表)之间存在1-N的关系,意味着一个用户可以有多个订单,而一个订单只属于一个用户。为了在Mybatis中处理这种关系,我们需要进行以下步骤: 1. **实体类设计**...

    MyBatis的关联映射彩色PPT版本.pptx

    MyBatis的关联映射是其核心特性之一,它允许开发者在处理数据库多表操作时,优雅地管理对象与对象间的关联关系。关联映射主要包括一对一、一对多和多对多三种关系,这些关系在实际的开发场景中非常常见。 在关系型...

    mybatis教程之resultmap_动力节点Java学院整理

    MyBatis ResultMap 详解 MyBatis 中的 ResultMap 是一个强大的元素,它描述如何从...ResultMap 是 MyBatis 中一个非常强大的元素,它可以帮助开发者快速地将结果集映射到 Java 实体类中,从而提高开发效率和代码质量。

Global site tag (gtag.js) - Google Analytics