MyBatis 中 resultMap 详解

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 getUserList(@Param(“uName”)String userName,@Param(“uRole”)int userRole);

(3)UserMapper.xml 中,编写查询用户列表的 SQL 语句,对表(mbms_user)和角色表(mbms_role)进行连表查询,使用 resultType 做自动映射。

<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 userList=new ArrayList();
  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 getUserList(@Param(“uName”)String userName,@Param(“uRole”)int userRole);

(3)UserMapper.xml 中,编写查询用户列表的 SQL 语句,对表(mbms_user)和角色表(mbms_role)进行连表查询,使用 resultMap 做自定义结果映射。

<select id="getUserList" resultMap="userList">SELECT u.*,r.roleName FROM`smbms_user` u,`smbms_role` rWHERE 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 userList=new ArrayList();
  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 中设置,代码如下:

MyBatis中resultMap详解相关推荐

  1. Mybatis的特性详解——动态SQL

    Mybatis的特性详解--动态SQL 前言 一.动态sql的元素 1.MyBatis if标签:条件判断 2.MyBatis choose.when和otherwise标签 3.MyBatis wh ...

  2. MyBatis SQL语句详解

    MyBatis SQL语句详解 1 CRUD标签 1.1 select 1.2 insert 1.3 update 1.4 delete 1.5 #{ }和${ }的区别 2 动态SQL 2.1 if ...

  3. 封装成jar包_通用源码阅读指导mybatis源码详解:io包

    io包 io包即输入/输出包,负责完成 MyBatis中与输入/输出相关的操作. 说到输入/输出,首先想到的就是对磁盘文件的读写.在 MyBatis的工作中,与磁盘文件的交互主要是对 xml配置文件的 ...

  4. MyBatis核心配置文件详解

    MyBatis核心配置文件详解 1.核心配置文件中的标签必须按照固定的顺序 2.properties标签 3.settings标签 4.typeAliases标签 5.environments标签 6 ...

  5. 如何配置Mybatis?(详解)

    如何配置Mybatis?(详解) 官网文档: https://mybatis.org/mybatis-3/zh/getting-started.html pom.xml <?xml versio ...

  6. Mybatis案例超详解

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

  7. mybatis的原理详解

    mybatis的原理详解 原理图 执行的原理图如下图所示: 配置文件分析 config.xml: <?xml version="1.0" encoding="UTF ...

  8. Mybatis的入门详解

    mybatis简介 MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为M ...

  9. Mybatis二级缓存详解

    Mybatis二级缓存 Mybatis相关全览 一.简介 二.一级缓存 1.入口 2.演示 案例一: 案例二: 3.总结 三.二级缓存 1.入口 2.如何开启二级缓存 cache-ref配置 cach ...

最新文章

  1. 教你几个写出原创文章的小方法
  2. 指定字符串按指定长度进行剪切
  3. windows2008的功能介紹及其与2003的差异
  4. 【caffe】windows下vs2013+opencv3.2.0+opencv_contrib(包含dnn)+cmake3.8编译与配置
  5. The first curriculum design experiment report in spring 2019
  6. getter和setter
  7. 2021年2月Harmonyos时候上线,华为HarmonyOS系统将于4月上线 MateX2首批升级
  8. CRC16循环冗余校验 RTU-MODBUS标准 Linux C
  9. 使用计算机效果不理想的应用,有效提高计算机应用课程教学效果的方法探究.doc...
  10. 7005.element-ui组件
  11. 怎么真正入行Web前端行业?JavaScript五大新特性是什么?
  12. PPT演讲放映技巧__备注的妙用
  13. Linux自动删除n天前备份
  14. linux内核之中断和异常
  15. PHP字符串部分方法
  16. JavaWeb项目实战
  17. xsmax进入dfu模式_苹果xsmax怎么进入dfu
  18. 昆山中创张嘉平:软件成为软件工程才容易成功
  19. 院士如何应对互联网的碎片化和复杂性?道翰天琼认知智能机器人平台API接口大脑为您揭秘。
  20. 转载知乎大神设置普通路由器支持IPV6

热门文章

  1. 高数——(反)三角函数及求导相关公式应用
  2. java spring面试题附pdf答案(最全版本持续更新)
  3. 笔记本搜索不到wifi怎么办?
  4. Adobe Photoshop CS6学习要点
  5. 【ECharts系列|04可视化大屏】ECharts可视化经典案例总结
  6. 玩转支付宝、微信零钱通、银行活期
  7. 如何让aboboo 便携版在citrix下使用(aboboo在IPAD上使用)aboboo苹果版
  8. WPS中如何嵌入电子签名?
  9. 一个程序教你花式示爱 1——波动心形线
  10. python 替换换行符_python按行读取文件,如何去掉换行符\\n