热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

【Mybatis】表关联和resultMap的使用

基础部分可以查看我的另一篇博客http:haohaoxuexi.iteye.comblog1333271MyBatis中在查询进行select映射的时候,返回类型可

基础部分可以查看我的另一篇博客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 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 getComments() {   
  48.         return comments;   
  49.     }   
  50.        
  51.     public void setComments(List 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. }  

 

其所对应的数据库表中存储有id,title,Content,Owner属性,那么当我们进行下面这样一个查询映射的时候

 

Xml代码  收藏代码
  1. <typeAlias alias&#61;"Blog" type&#61;"com.tiantian.mybatis.model.Blog"/>  
  2. <select id&#61;"selectBlog" parameterType&#61;"int" resultType&#61;"Blog">  
  3.         select * from t_blog where id &#61; #{id}   
  4. select>  

     


 MyBatis会自动创建一个ResultMap对象&#xff0c;然后基于查找出来的属性名进行键值对封装&#xff0c;然后再看到返回类型是Blog对象&#xff0c;再从ResultMap中取出与Blog对象对应的键值对进行赋值。

当返回类型直接是一个ResultMap的时候也是非常有用的&#xff0c;这主要用在进行复杂联合查询上&#xff0c;因为进行简单查询是没有什么必要的。我们先看看一个返回类型为ResultMap的简单查询&#xff0c;再看看复杂查询的用法。

简单查询的写法

 

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

     


 select映射中resultMap的值是一个外部resultMap的id&#xff0c;表示返回结果映射到哪一个resultMap上&#xff0c;外部resultMap的type属性表示该resultMap的结果是一个什么样的类型&#xff0c;这里是Blog类型&#xff0c;那么MyBatis就会把它当作一个Blog对象取出。resultMap节点的子节点id是用于标识该对象的id的&#xff0c;而result子节点则是用于标识一些简单属性的&#xff0c;其中的Column属性表示从数据库中查询的属性&#xff0c;Property则表示查询出来的属性对应的值赋给实体对象的哪个属性。简单查询的resultMap的写法就是这样的。接下来看一个复杂一点的查询。

有一个Comment类&#xff0c;其中有一个Blog的引用&#xff0c;表示是对哪个Blog的Comment&#xff0c;那么我们在查询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 &#61; 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 &#61; id;   
  19.     }   
  20.   
  21.     public String getContent() {   
  22.         return content;   
  23.     }   
  24.   
  25.     public void setContent(String content) {   
  26.         this.content &#61; content;   
  27.     }   
  28.   
  29.     public Date getCommentDate() {   
  30.         return commentDate;   
  31.     }   
  32.   
  33.     public void setCommentDate(Date commentDate) {   
  34.         this.commentDate &#61; commentDate;   
  35.     }   
  36.   
  37.     public Blog getBlog() {   
  38.         return blog;   
  39.     }   
  40.   
  41.     public void setBlog(Blog blog) {   
  42.         this.blog &#61; blog;   
  43.     }   
  44.        
  45.     public String toString() {   
  46.         return blog &#43; "\n ----------------评论-----------------\n id: " &#43; id &#43; "\n content: " &#43; content &#43; "\n commentDate: " &#43; commentDate;   
  47.     }   
  48.        
  49. }  

  

其写法是这样的

 

Xml代码  收藏代码
  1.   
  2.     <resultMap type&#61;"Comment" id&#61;"CommentResult">  
  3.         <association property&#61;"blog" select&#61;"selectBlog" column&#61;"blog" javaType&#61;"Blog"/>  
  4.     resultMap>  
  5.        
  6.     <select id&#61;"selectComment" parameterType&#61;"int" resultMap&#61;"CommentResult">  
  7.         select * from t_Comment where id &#61; #{id}   
  8.     select>  
  9.        
  10.     <select id&#61;"selectBlog" parameterType&#61;"int" resultType&#61;"Blog">  
  11.         select * from t_Blog where id &#61; #{id}   
  12.     select>  

其访问情况是这样的&#xff0c;先是请求id为selectComment的select映射&#xff0c;然后得到一个id为CommentResult的ResultMap对象&#xff0c;我们可以看到在对应的resultMap的返回类型是一个Comment对象&#xff0c;其中只有一个association节点&#xff0c;而没有像前面说的简单查询所对应的id&#xff0c;result子节点&#xff0c;但是其仍会把对应的id等属性赋给Comment对象&#xff0c;这就是前面所说的MyBatis拥有自动封装功能&#xff0c;只要你提供了返回类型&#xff0c;MyBatis会根据自己的判断来利用查询结果封装对应的对象&#xff0c;所以前面的简单查询中&#xff0c;如果你不在resultMap中明确的指出id对应哪个字段&#xff0c;title对应哪个字段&#xff0c;MyBatis也会根据自身的判断来帮你封装&#xff0c;MyBatis的自身判断是把查询的field或其对应的别名与返回对象的属性进行比较&#xff0c;如果相匹配且类型也相匹配&#xff0c;MyBatis则会对其进行赋值。在上面对应的resultMap中关联了一个blog属性&#xff0c;其对应的JAVA类型为Blog&#xff0c;在上述的写法中&#xff0c;关联对象是通过子查询来进行关联的&#xff0c;当然也可以直接通过关联查询来进行关联。上面的association子节点中&#xff0c;Property属性表示是resultMap返回类型的哪个关联属性&#xff0c;对于上面的例子就是Comment管理的blog属性&#xff1b;select表示进行哪个select映射来映射对应的关联属性&#xff0c;即会去请求id为select所对应的值的select映射 来查询出其所关联的属性对象&#xff1b;Column表示当前关联对象在id为CommentResult的resultMap中所对应的键值对&#xff0c;该键值对将作为对关联对象子查询的参数&#xff0c;即将把在selectComment中查询出来的blog属性的值作为参数传给进行关联对象blog的子查询selectBlog的参数&#xff1b;javaType表示当前关联对象在JAVA中是什么类型。

 

上述介绍的是一对一或一对多的情况下&#xff0c;对一的一方的关联的查询。在实际应用中还有一个用的比较多的应用是通过一的一方查出对应的多的一方&#xff0c;在拿出多的一方的时候也同样要把一的一方关联上&#xff0c;即在上述例子中&#xff0c;在拿出Blog对象的时候&#xff0c;就把其对应的Comment全部拿出来&#xff0c;在拿出Comment的时候也还是需要把其对应的Blog拿出来&#xff0c;这是在JAVA中通过一次请求就拿出来的。写法如下&#xff1a;

 

Xml代码  收藏代码
  1.   
  2.     <resultMap type&#61;"Blog" id&#61;"BlogResult">  
  3.         <id column&#61;"id" property&#61;"id"/>  
  4.         <collection property&#61;"comments" select&#61;"selectCommentsByBlog" column&#61;"id" ofType&#61;"Comment">collection>  
  5.     resultMap>  
  6.   
  7.     <resultMap type&#61;"Comment" id&#61;"CommentResult">  
  8.         <association property&#61;"blog" javaType&#61;"Blog" column&#61;"blog" select&#61;"selectBlog"/>  
  9.     resultMap>  
  10.   
  11.     <select id&#61;"selectBlog" parameterType&#61;"int" resultMap&#61;"BlogResult">  
  12.         select * from t_blog where id &#61; #{id}   
  13.     select>  
  14.   
  15.   
  16.     <select id&#61;"selectCommentsByBlog" parameterType&#61;"int" resultMap&#61;"CommentResult">  
  17.         select * from t_Comment where blog &#61; #{blogId}   
  18.     select>  

     


上述请求的入口是id为selectBlog的select映射&#xff0c;返回结果为id为BlogResult的resultMap&#xff0c;id为BlogResult的类型为Blog&#xff0c;其中指定了id的属性和字段&#xff0c;指定id将对MyBatis内部的构造作用非常大。其中关联了一个comments对象&#xff0c;因为一个Blog可以有很多Comment&#xff0c;该comments为一个集合&#xff0c;所以用集合collection进行映射&#xff0c;其中的select还是表示进行哪个子查询来查询对应的comments&#xff0c;column表示把上述查出来的哪个字段值当作参数传给子查询&#xff0c;ofType也是表示返回类型&#xff0c;这里的返回类型是集合内部的类型&#xff0c;之所以用ofType而不是用type是MyBatis内部为了和关联association进行区别。 

 

 

 

测试代码&#xff1a;

 

Java代码  收藏代码
  1. &#64;Test  
  2. public void selectCommentsByBlogTest() {   
  3.     SqlSession session &#61; Util.getSqlSessionFactory().openSession();   
  4.     CommentMapper commentMapper &#61; session.getMapper(CommentMapper.class);   
  5.     List comments &#61; commentMapper.selectCommentsByBlog(6);   
  6.     for (Comment comment : comments)   
  7.         System.out.println(comment);   
  8.     session.close();   
  9. }   
  10.   
  11. /**  
  12.  * 查询单条记录  
  13.  */  
  14. &#64;Test  
  15. public void testSelectOne() {   
  16.     SqlSession session &#61; Util.getSqlSessionFactory().openSession();   
  17.     BlogMapper blogMapper &#61; session.getMapper(BlogMapper.class);   
  18.     Blog blog &#61; blogMapper.selectBlog(6);   
  19.     List comments &#61; blog.getComments();   
  20.     if (comments !&#61; null) {   
  21.         System.out.println("--------------Comments Size------------" &#43; comments.size());   
  22.         for (Comment comment : comments)   
  23.             System.out.println(comment);   
  24.     }   
  25.     session.close();   
  26. }  


推荐阅读
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
  • Spring源码解密之默认标签的解析方式分析
    本文分析了Spring源码解密中默认标签的解析方式。通过对命名空间的判断,区分默认命名空间和自定义命名空间,并采用不同的解析方式。其中,bean标签的解析最为复杂和重要。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • Linux重启网络命令实例及关机和重启示例教程
    本文介绍了Linux系统中重启网络命令的实例,以及使用不同方式关机和重启系统的示例教程。包括使用图形界面和控制台访问系统的方法,以及使用shutdown命令进行系统关机和重启的句法和用法。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • MyBatis错题分析解析及注意事项
    本文对MyBatis的错题进行了分析和解析,同时介绍了使用MyBatis时需要注意的一些事项,如resultMap的使用、SqlSession和SqlSessionFactory的获取方式、动态SQL中的else元素和when元素的使用、resource属性和url属性的配置方式、typeAliases的使用方法等。同时还指出了在属性名与查询字段名不一致时需要使用resultMap进行结果映射,而不能使用resultType。 ... [详细]
  • 怀疑是每次都在新建文件,具体代码如下 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • r2dbc配置多数据源
    R2dbc配置多数据源问题根据官网配置r2dbc连接mysql多数据源所遇到的问题pom配置可以参考官网,不过我这样配置会报错我并没有这样配置将以下内容添加到pom.xml文件d ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • 使用Ubuntu中的Python获取浏览器历史记录原文: ... [详细]
  • 本文介绍了Oracle数据库中tnsnames.ora文件的作用和配置方法。tnsnames.ora文件在数据库启动过程中会被读取,用于解析LOCAL_LISTENER,并且与侦听无关。文章还提供了配置LOCAL_LISTENER和1522端口的示例,并展示了listener.ora文件的内容。 ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
author-avatar
化合价steuart_968
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有