resultMap 是 Mybatis 最强大的元素之一,它可以将查询到的复杂数据(比如查询到几个表中数据)映射到一个结果集当中。如在实际应用中,有一个表为(用户角色表),通过查询用户表信息展示页面,在(用户表)中存在用户角色表 id ,在实际列表页的展示中,用户关注的是用户角色名称,而不是角色 id。解决此类问题可以通过 resultMap 来映射自定义结果。 使用 resultMap 做自定义结果映射,字段名可以不一致,并且还可以指定要显示的列,比较灵活,应用也广泛(推荐使用)。

resultMap 知识点

  resultMap 元素用来描述如何将结果集映射到 Java 对象,使用 resultMap 对列表展示所需的必要字段来进行自动映射,特别是当数据库的字段名和实体类 POJO 中的属性名不一致的情况下,比如角色名称,字段名/列名 column 是 roleName,而 User 对象的属性名则为 userRoleName ,此时就需要做映射。

  resultMap 元素的属性值和子节点

     id 属性:唯一标识,此 id 值用于 select 元素 resultMap 属性的引用。

     type 属性:表示该 resultMap 的映射结果类型。

      result 子节点:用于标识一些简单属性,其中 column 属性表示从数据库中查询的字段名或别名, property 属性则表示查询出来的字段对应的值赋给实体对象的哪个属性。

  说明:MyBatis 中在对查询进行 select 映射的时候,返回类型可以用 resultType 也可以用 resultMap ,resultType和 resultMap 有一定关联和区别,应用场景也不同。

resultType 和 resultMap 区别

    resultType:直接表示返回类型,包括基础数据类型和复杂数据类型。
    resultMap 则是对外部 resultMap 定义的引用,对应外部 resultMap 的 id,表示返回结果映射到哪一个 resultMap 上。它的应用场景一般是:数据库字段信息与对象属性不一致或者需要做复杂的联合查询以便自由控制映射结果。

    说明:注意,MyBatis 中使用 resultType 做自动映射,一定要注意:字段名和 POJO 的属性名必须一致。若不一致,则需要给字段起别名,保证别名与属性名一致。

resultType 和 resultMap 关联

  在 MyBatis 进行查询映射的时候,其实查询出来的每个字段值都放在一个对应的 Map 里面,其中键是字段名,值则是其对应的值。当 select 元素提供的返回类型属性是 resultType 的时候, MyBatis 会将 Map 里面的键值对取出赋给 resultType 所指定的对象对应的属性(即调用对应的对象里的属性的 setter 方法进行填充)。正因为如此,当使用 resultType 的时候,直接在后台就能接收到其相应的对象属性值。由此可看出,其实 MyBatis 的每个查询映射的返回类型都是 resultMap ,只是当我们提供的返回类型属性是 resultType 的时候, MyBatis 会自动把对应的值赋给 resultType 所指定对象的属性; 而当我们提供的返回类型是 resultMap 的时候,因为 Map 不能很好地表示领域模型,我们就需要通过进一步的定义把它转化为对应的实体对象。
  当返回类型是 resultMap 时,也是非常有用的,这主要用在进行复杂联合查询上,当然在进行简单查询时是没有什么必要的,使用 resultType 足以。

  说明:

    1、Mybatis 是对返回的结果的每一行做映射的,因此在指定 resultType 或者 resultMap 返回类型时应特别注意是一行的类型而不是所有。

    2、MyBatis 中在查询进行 select 映射的时候,返回类型可以用 resultType,也可以用 resultMap,resultType 是直接表示返回类型的,而 resultMap 则是对外部 resultMap 的引用,在 MyBatis 的 select 元素中,resultType 和 resultMap 本质上是一样的,都是 Map 数据结构。但需要明确一点: resultType 属性和 resultMap 属性绝对不能同时存在,只能二者选 其一使用。

    3、在 MyBatis 中,使用 resultMap 能够进行自动映射匹配的前提是字段名和属性名需要一致,在默认映射级别(PARTIAL)情况下,若一致,即使没有做属性名和字段名的匹配,也可以在后台获取到未匹配过的属性值;若不一致,且在 resultMap 里没有做映射,那么就无法在后台获取并输出。

 案例解析:根据用户名和用户角色 id 查询出用户表中用户信息,要求用户角色要显示角色名称而不是角色 id。

  方式 1 :使用 resultType 做自动映射 (了解即可)

  注意,MyBatis 中使用 resultType 做自动映射,一定要注意:字段名和 POJO 的属性名必须一致。若不一致,则需要给字段起别名,保证别名与属性名一致。

(1)修改实体类 POJO:User.java,增加 userRoleName 属性,添加对应的 get 和 set 方法。

   private String userRoleName; //用户角色名称

   public String getUserRoleName() {
return userRoleName;
}
public void setUserRoleName(String userRoleName) {
this.userRoleName = userRoleName;
} (2)UserMapper.java 接口中编写查询用户列表的 getUserList()方法。   /**
* 根据用户名称(模糊查询)和用户角色查询用户列表(要求用户角色要显示角色名称而不是角色 id)
* @param userName 用户名称
* @param userRole 用户角色
* @return
*/
public List<User> getUserList(@Param("uName")String userName,@Param("uRole")int userRole); (3)UserMapper.xml 中,编写查询用户列表的 SQL 语句,对表(mbms_user)和角色表(mbms_role)进行连表查询,使用 resultType 做自动映射。 <!-- 根据用户名称(模糊查询)和用户角色查询用户列表(要求用户角色要显示角色名称而不是角色 id) -->
<select id="getUserList" resultType="user">
SELECT u.*,r.roleName AS userRoleName FROM `smbms_user` u,`smbms_role` r
WHERE u.`userRole`=r.`id`
AND userRole=#{uRole}
AND userName LIKE CONCAT('%',#{uName},'%')
</select> 说明:使用 resultType 做自动映射,要求数据库字段名必须和 POJO 属性名一致。因此要给数据库字段取别名,别名为 userRoleName 。 (4)单元测试类 @Test //测试根据用户名称(模糊查询)和用户角色查询用户列表(要求用户角色要显示角色名称而不是角色 id)
public void testGetUserList(){
 List<User> userList=new ArrayList<User>();
  String userName="赵";
int userRole=2;
userList=session.getMapper(UserMapper.class).getUserList(userName, userRole);
for (User user : userList) {
System.out.println(user);
}
}
    
   说明:此种方法必须给 r.roleName 取别名为 userRoleName 。

方式 2 :使用 resultMap 来自定义映射结果(推荐使用)

    通过 resultMap 来自定义映射结果。 使用 resultMap 做自定义结果映射,字段名可以不一致,并且还可以指定要显示的列,比较灵活,应用也广泛(推荐使用)

(1)修改实体类 POJO:User.java,增加 userRoleName 属性,添加对应的 get 和 set 方法。

   private String userRoleName; //用户角色名称

   public String getUserRoleName() {
return userRoleName;
}
public void setUserRoleName(String userRoleName) {
this.userRoleName = userRoleName;
} (2)UserMapper.java 接口中编写查询用户列表的 getUserList()方法。   /**
* 根据用户名称(模糊查询)和用户角色查询用户列表(要求用户角色要显示角色名称而不是角色 id)
* @param userName 用户名称
* @param userRole 用户角色
* @return
*/
public List<User> getUserList(@Param("uName")String userName,@Param("uRole")int userRole); (3)UserMapper.xml 中,编写查询用户列表的 SQL 语句,对表(mbms_user)和角色表(mbms_role)进行连表查询,使用 resultMap 做自定义结果映射。 <!-- 根据用户名称(模糊查询)和用户角色查询用户列表(要求用户角色要显示角色名称而不是角色 id) -->
<select id="getUserList" resultMap="userList">
SELECT u.*,r.roleName FROM
`smbms_user` u,`smbms_role` r
WHERE u.`userRole`=r.`id`
AND userRole=#{uRole}
AND userName LIKE CONCAT('%',#{uName},'%')
</select> <resultMap type="user" id="userList">
<result property="id" column="id" />
<result property="userCode" column="userCode" />
<result property="userName" column="userName" />
<result property="phone" column="phone" />
<result property="birthday" column="birthday" />
<result property="gender" column="gender" />
<result property="userRole" column="userRole" /> <result property="userRoleName" column="roleName" />
</resultMap> (4)单元测试类
@Test //测试根据用户名称(模糊查询)和用户角色查询用户列表(要求用户角色要显示角色名称而不是角色 id)
public void testGetUserList(){
 List<User> userList=new ArrayList<User>();
  String userName="赵";
int userRole=2;
userList=session.getMapper(UserMapper.class).getUserList(userName, userRole);
for (User user : userList) {
System.out.println(user);
}
}
   说明:resultMap 做自定义结果映射,与 MyBatis 的自动映射级别(autoMappingBehavior)有关。

注意点

  在 MyBatis 中,使用 resultMap 能够进行自动映射匹配的前提是字段名和属性名需要一致,在默认映射级别(PARTIAL)情况下,若一致,即使没有做属性名和字段名的匹配,也可以在后台获取到未匹配过的属性值;若不一致,且在 resultMap 里没有做映射,那么久无法在后台获取并输出。

MyBatis 的自动映射级别  

  FULL:自动匹配所有。

  PARTIAL(默认):自动匹配所有属性,有内部嵌套(association,collection)的除外。

  NONE:禁止自动匹配。

  MyBatis 的自动映射级别,需要在 mybatis-config.xml 的 settings 中设置,代码如下:

 <settings>
<!--设置 resultMap 的自动映射级别-->
<setting name="autoMappingBehavior" value="PARTIAL" />
</settings>

 

MyBatis 中 resultMap 详解的更多相关文章

  1. Java SSM框架之MyBatis3(五)MyBatis之ResultMap详解

    resultMap是Mybatis最强大的元素,它可以将查询到的复杂数据(比如查询到几个表中数据)映射到一个结果集当中. resultMap包含的元素: <!--column不做限制,可以为任意 ...

  2. ResultMap详解

    MyBatis:ResultMap详解   一.前言   MyBatis是基于“数据库结构不可控”的思想建立的,也就是我们希望数据库遵循第三范式或BCNF,但实际事与愿违,那么结果集映射就是MyBat ...

  3. mybatis代码生成器配置文件详解

    mybatis代码生成器配置文件详解 更多详见 http://generator.sturgeon.mopaas.com/index.html http://generator.sturgeon.mo ...

  4. MyBatis Mapper XML 详解

    MyBatis Mapper XML 详解 MyBatis 真正的力量是在映射语句中.这里是奇迹发生的地方.对于所有的力量,SQL 映射的 XML 文件是相当的简单.当然如果你将它们和对等功能的 JD ...

  5. Mybatis源码详解系列(四)--你不知道的Mybatis用法和细节

    简介 这是 Mybatis 系列博客的第四篇,我本来打算详细讲解 mybatis 的配置.映射器.动态 sql 等,但Mybatis官方中文文档对这部分内容的介绍已经足够详细了,有需要的可以直接参考. ...

  6. 深入浅出mybatis之启动详解

    深入浅出mybatis之启动详解 MyBatis功能丰富,但使用起来非常简单明了,今天我们来追踪一下它的启动过程. 目录 如何启动MyBatis 如何使用MyBatis MyBatis启动过程 如何启 ...

  7. MyBatis核心配置文件详解

    ------------------------siwuxie095                                     MyBatis 核心配置文件详解         1.核心 ...

  8. 《深入理解mybatis原理2》 Mybatis初始化机制详解

    <深入理解mybatis原理> Mybatis初始化机制详解 对于任何框架而言,在使用前都要进行一系列的初始化,MyBatis也不例外.本章将通过以下几点详细介绍MyBatis的初始化过程 ...

  9. Mybatis案例超详解(上)

    Mybatis案例超详解(上) 前言: 本来是想像之前一样继续跟新Mybatis,但由于种种原因,迟迟没有更新,快开学了,学了一个暑假,博客也更新了不少,我觉得我得缓缓,先整合一些案例练练,等我再成熟 ...

随机推荐

  1. forceStopPackage与killBackgroundProcesses方法

    最近了解一键清理功能,需要实现强制关闭进程的功能.下面介绍下killBackgroundProcesses()方法和forceStopPackage()方法. killBackgroundProces ...

  2. go 安装方法

    wget https://storage.googleapis.com/golang/go1.5.linux-amd64.tar.gz sudo tar -C /usr/local -xzf go1. ...

  3. 【BZOJ 4353】 Play with tree

    [题目链接] 点击打开链接 [算法] 树链剖分 对于线段树的每个节点,记录这段区间的最小值,最小值的个数,值为0的个数,此外,还要维护两个懒惰标记 [代码] 本题细节很多,写程序时要认真严谨! #in ...

  4. 昆石VOS3000_2.1.3.2完整安装包及安装脚本

    安装包下载地址:http://www.51voip.org/post/55.html 安装教程: 上传安装包 核实 关闭selinux 是否关闭 /usr/sbin/sestatus -v cd /r ...

  5. [App Store Connect帮助]五、管理构建版本(3)在您提交以供审核前选择构建版本

    在提交 App 至“App 审核”前,请(从您为该版本上传的所有构建版本中)选择您想要提交的版本.一个 App Store 版本仅可关联一个构建版本.但是,在提交该版本至“App 审核”之前,您可以任 ...

  6. ACM_下一个排列

    The Next Permutation Time Limit: 2000/1000ms (Java/Others) Problem Description: For this problem, yo ...

  7. 309 Best Time to Buy and Sell Stock with Cooldown 买股票的最佳时间含冷冻期

    Say you have an array for which the ith element is the price of a given stock on day i.Design an alg ...

  8. Android常用依赖库搜集

    图片处理 CircleImageView Git地址:https://github.com/hdodenhof/CircleImageView 图片依赖库 glide Git地址:https://gi ...

  9. [转] Android利用Fiddler进行网络数据抓包

    主要介绍Android及IPhone手机上如何利用Fiddler进行网络数据抓包,比如我们想抓某个应用(微博.微信.墨迹天气)的网络通信请求就可以利用这个方法. Mac 下请使用 Charles 代替 ...

  10. UVM基础之-------uvm factory机制override<博>

    override功能是UVM中一个比较重要的功能,这个功能也是在factory里面实现的,我们会在env或者具体的case中使用override功能. class case_x extends bas ...