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<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 详解的更多相关文章
- Java SSM框架之MyBatis3(五)MyBatis之ResultMap详解
resultMap是Mybatis最强大的元素,它可以将查询到的复杂数据(比如查询到几个表中数据)映射到一个结果集当中. resultMap包含的元素: <!--column不做限制,可以为任意 ...
- ResultMap详解
MyBatis:ResultMap详解 一.前言 MyBatis是基于“数据库结构不可控”的思想建立的,也就是我们希望数据库遵循第三范式或BCNF,但实际事与愿违,那么结果集映射就是MyBat ...
- mybatis代码生成器配置文件详解
mybatis代码生成器配置文件详解 更多详见 http://generator.sturgeon.mopaas.com/index.html http://generator.sturgeon.mo ...
- MyBatis Mapper XML 详解
MyBatis Mapper XML 详解 MyBatis 真正的力量是在映射语句中.这里是奇迹发生的地方.对于所有的力量,SQL 映射的 XML 文件是相当的简单.当然如果你将它们和对等功能的 JD ...
- Mybatis源码详解系列(四)--你不知道的Mybatis用法和细节
简介 这是 Mybatis 系列博客的第四篇,我本来打算详细讲解 mybatis 的配置.映射器.动态 sql 等,但Mybatis官方中文文档对这部分内容的介绍已经足够详细了,有需要的可以直接参考. ...
- 深入浅出mybatis之启动详解
深入浅出mybatis之启动详解 MyBatis功能丰富,但使用起来非常简单明了,今天我们来追踪一下它的启动过程. 目录 如何启动MyBatis 如何使用MyBatis MyBatis启动过程 如何启 ...
- MyBatis核心配置文件详解
------------------------siwuxie095 MyBatis 核心配置文件详解 1.核心 ...
- 《深入理解mybatis原理2》 Mybatis初始化机制详解
<深入理解mybatis原理> Mybatis初始化机制详解 对于任何框架而言,在使用前都要进行一系列的初始化,MyBatis也不例外.本章将通过以下几点详细介绍MyBatis的初始化过程 ...
- Mybatis案例超详解(上)
Mybatis案例超详解(上) 前言: 本来是想像之前一样继续跟新Mybatis,但由于种种原因,迟迟没有更新,快开学了,学了一个暑假,博客也更新了不少,我觉得我得缓缓,先整合一些案例练练,等我再成熟 ...
随机推荐
- luogu 1901 发射站
题目大意: 一个数列,它左边第一个比它高的人和右边第一个比它高的人要加上它的权值 思路: 单调栈维护一个单调递减的栈 正反各维护一遍 #include<iostream> #include ...
- 【转载】Java - Wait & Notify
[本文转自]http://www.cnblogs.com/dolphin0520/p/3920385.html 这三个方法的文字描述可以知道以下几点信息: 1)wait().notify()和noti ...
- bzoj 1914: [Usaco2010 OPen]Triangle Counting 数三角形【叉积+极角排序+瞎搞】
参考:https://blog.csdn.net/u012288458/article/details/50830498 有点神啊 正难则反,考虑计算不符合要求的三角形.具体方法是枚举每个点,把这个点 ...
- python实现对excel数据进行修改/添加
import osimport xlrdfrom xlutils.copy import copydef base_dir(filename=None): return os.path.join(os ...
- Nginx(三) 常用配置整理
#定义Nginx运行的用户和用户组 user www www; #nginx进程数,建议设置为等于CPU总核心数. worker_processes 8; #全局错误日志定义类型,[ debug | ...
- phpAnalysis调试接口
phpAnalysis是一款轻量级非侵入式PHP应用性能分析器,适用于开发.测试及生产环境部署使用,方便开发及测试工程师诊断性能问题: 通过tideways收集PHP程序单步运行过程中所有的函数调用时 ...
- java io 文件下载
/** * 文件下载 * @param response * @param downloadPath * @param docName */ public void downLoadFile( Htt ...
- [C陷阱和缺陷] 第2章 语法“陷阱”
第2章 语法陷阱 2.1 理解函数声明 当计算机启动时,硬件将调用首地址为0位置的子例程,为了模拟开机时的情形,必须设计出一个C语言,以显示调用该子例程,经过一段时间的思考,得出语句如下: ( * ...
- PROTEUS快捷键与部分知识点
缩放 有以下几种方法对原理图进行缩放: 移动鼠标需要所放的地方,滚动鼠标滑轮进行缩放. 移动师表需要缩放的地方,按键盘F6放大,F7缩小 按下ShIFT键,鼠标左键拖拽出需要放大的区域,这叫SHIFT ...
- Quartz.Net学习笔记(2)-简介
一.Quartz.Net是什么 1.来源 Quartz.Net是一个开源的作业调度框架: 2.下载地址 官网地址:http://www.quartz-scheduler.net/documentati ...