MyBatis标签之Select resultType和resultMap
摘要:介绍MyBatis 中Select标签的两个属性resultType和resultMap及其区别。
1 MyBatis动态SQL之if 语句
2 MyBatis动态sql之where标签|转
3 MyBatis动态SQL之set标签|转
4 MyBatis动态SQL之trim元素|转
5 MyBatis动态sql中foreach标签的使用
6 MyBatis动态SQL之choose(when、otherwise)语句
7 MyBatis动态SQL之bind标签|转
8 MyBatis标签之Select resultType和resultMap
MyBatis常用动态标签大全见上述URL,它们大概分为如下四类:
标签 | 作用 | 使用场景 |
---|---|---|
foreach | 循环语句 | 批量添加或者批量查询 |
if | 条件判断语句 | 单条件分支判断 |
choose、when、otherwise | 类似 Java 中的 switch、case、default 语句 | 多条件分支判断 |
trim、where、set | 辅助标签 | 用于处理一些条件查询 |
在MyBatis中有一个ResultMap标签,它是为了映射select标签查询出来的结果集,其主要作用是将实体类中的字段与数据库表中的字段进行关联映射。
前言
Mybatis 中 select 标签有两个属性 resultType 和 resultMap,用于在mapper.xml文件中配置返回结果类型,工作中经常使用到它们。那么在日常开发中,应该如何正确的选择呢?下面我们对这两个属性分别进行讲解和演示。
结果类型resultType
resultType直译就是结果的类型,可以设置为期望从select 语句中返回结果的类的全限定名或别名。resultType使用场景如下:
如果查询结果只是返回一个值,比如返回String、map或int,那么可以使用resultType指定简单类型作为输出结果。
我们先了解一个resultType的简单映射语句示例,它没有显式地指定 resultMap
。比如:
<sql id="resultTypeColumn">
id, username, hashedPassword
</sql>
<select id="selectUsers" resultType="map">
select
<include refid="resultTypeColumn"/>
from some_table
where id = #{id}
</select>
上述语句只是简单地将所有的列映射到 HashMap
的键上,这由 resultType
属性指定。此处对查询字段用了一个 sql 标签进行封装,该sql 片段可复用。
还有一种情况就是如果数据库表的字段名和实体bean对象的属性名一样。 虽然在大部分情况下都够用,但是 HashMap 并不是一个很好的领域模型;你的程序更可能会使用 JavaBean 或 POJO(普通老式 Java 对象)作为领域模型,MyBatis 对两者都提供了支持。看看下面这个 JavaBean:
package com.someapp.model;
public class User {
private int id;
private String username;
private String hashedPassword;
// omit getter,setter and toString
}
基于 JavaBean 的规范,上面这个类有 3 个属性:id,username 和 hashedPassword,它们会对应到 select 语句中的列名。这样的一个 JavaBean 可以被映射到 ResultSet
,就像映射到 HashMap
一样简单。
<select id="selectUsers" resultType="com.someapp.model.User">
select
<include refid="resultTypeColumn"/>
from some_table
where id = #{id}
</select>
类型别名是你的好帮手,关于如何设置类型别名,请移步《Spring Boot MyBatis使用type-aliases-package自定义类别名》。使用别名后就可以不用输入类的全限定名了。譬如:
<select id="selectUsers" resultType="User">
select
<include refid="resultTypeColumn"/>
from some_table
where id = #{id}
</select>
在此情况下,MyBatis 会在幕后自动创建一个 resultMap
,再根据属性名来映射列到 JavaBean 的属性上。如果列名和属性名不能匹配上,可以在 SELECT 语句中设置列别名(这是一个基本的 SQL 特性)来完成匹配。例如:
<sql id="resultTypeColumn">
user_id as "id",
user_name as "userName",
hashed_password as "hashedPassword"
</sql>
<select id="selectUsers" resultType="map">
select
<include refid="resultTypeColumn"/>
from some_table
where id = #{id}
</select>
注意,如果返回的是集合,那应该设置为集合包含的类型,而不是集合本身的类型。
结果映射resultMap
resultMap
直译就是结果映射,该元素是 MyBatis 中最重要最强大的元素。与 resultType 相比,resultMap就要强大许多,它不仅能够用于简单查询,还能用于级联查询以及设置缓存,功能可谓是十分的强大。它可以让你从 90% 的 JDBC ResultSets
数据提取代码中解放出来,并在一些情形下允许你进行一些 JDBC 不支持的操作。实际上,在为一些比如连接的复杂语句编写映射代码的时候,一份 resultMap
能够代替实现同等功能的数千行代码。ResultMap 的设计思想是,对简单的语句做到零配置,对于复杂一点的语句,只需要描述语句之间的关系就行了。温馨提示:resultType 和 resultMap 之间只能同时使用一个。
resultMap标签属性
resultMap 标签的属性值包括两个:
id 属性:唯一标识,此 id 值用于 select 标签 resultMap 属性的引用。
type 属性:表示该 resultMap 的映射结果类型,可以为类的全限定名或者别名。
resultMap子标签包括如下几个 :
子标签 | 功能 | 备注 |
---|---|---|
id | 指定查询列中的唯一标识,如果有多个列组成唯一标识,配置多个id | 可以不用 |
result | 用于标识一些简单属性,包括column和property两个属性 | 常用 |
association | 在主表的pojo中嵌套另一个表的pojo | 不推荐使用 |
collection | 把查询到的多条记录映射到集合对象 | 不推荐使用 |
result标签的属性包括两个:
- column:数据库字段名或别名。
- property:实体类中的属性,和column属性一一对应。
resultMap使用示例
下面使用一个简单的例子,来介绍 resultMap 的使用方法。虽然上一节中的例子不用显式配置 resultMap
,但为了讲解,我们来看看如果显式使用外部的 resultMap
会怎样;这也是解决列名和bean名不匹配的另外一种方式。定义一个resultMap:
<resultMap id="userResultMap" type="User">
<id property="id" column="user_id" />
<result property="username" column="user_name"/>
<result property="password" column="hashed_password"/>
</resultMap>
然后在引用它的语句中设置 resultMap
属性就行了(注意我们去掉了 resultType
属性)。比如:
<select id="selectUsers" resultMap="userResultMap">
select user_id, user_name, hashed_password
from some_table
where id = #{id}
</select>
resultType和resultMap的区别
下面了解一下MyBatis中数据转换机制:在进行查询映射的时候,其实查询出来的每一个属性都是放在一个对应的Map里面,其中键是属性名,值则是其对应的值。当提供的返回类型属性是resultType的时候,MyBatis会将Map里面的键值对取出赋给resultType所指定的对象对应的属性。所以,其实MyBatis的每一个查询映射的返回类型都是ResultMap,只是当我们提供的返回类型属性是resultType的时候,MyBatis自动的把对应的值赋给resultType所指定对象的属性,而当提供的返回类型是resultMap的时候,因为Map不能很好表示领域模型,我们就需要自己把它转化为对应的对象,这常常在复杂查询中很有作用。
言归正传,resultType和resultMap到底有什么区别呢?
resultType不需要配置,但是resultMap要配置一下。resultType是直接指定返回类型的,而使用resultMap时,需要在外部ResultMap标签中,设置数据库表的字段名和实体bean对象类的属性的一一对应关系。设置后,就算数据库的字段名和实体类的属性名不一样也没有关系,mybatis依然会给映射出来,所以resultMap要更强大一些。
就像上面说的那样,如果查询出来数据库字段名(包括字段别名)和要封装的实体bean对象属性值不相同时,只能使用resultMap来返回结果。
还有一个区别是resultMap可以用在复杂联合查询上,而resultType不可以。关于这一点,大家可以去Mybatis官网了解一下,这里点到为止。
结束语
至此,大家已经了解了resultType和resultMap的基本用法,在日常业务开发中已经可以游刃有余了。如果想更上一层楼,掌握更多关于resultMap的高级用法,请移步Mybatis官网。
当你遇到这个话题的时候,你通常怎么理解呢?你碰到过特别精彩、让人印象深刻的回答吗?欢迎大家积极留言交流。
Reference
- https://mybatis.org/mybatis-3/zh/sqlmap-xml.html
- https://baijiahao.baidu.com/s?id=1696473444790362129&wfr=spider&for=pc
MyBatis标签之Select resultType和resultMap的更多相关文章
- Mybatis中输出映射resultType与resultMap的区别
Mybatis中输出映射resultType与resultMap的区别 (原文地址:http://blog.csdn.net/acmman/article/details/46509375) 一.re ...
- 【mybatis笔记】 resultType与resultMap的区别
序言: 昨天做一个项目,看到很多刚开始用mybatis的同事对于resultType和resultMap的理解与使用含糊不清,这里我试图用最好理解的说法写一写,欢迎大家勘误. 两者异同: 相同点:re ...
- MyBatis学习-映射文件标签篇(select、resultMap)
MyBatis 真正的核心在映射文件中.比直接使用 JDBC 节省95%的代码.而且将 SQL 语句独立在 Java 代码之外,可以进行更为细致的 SQL 优化. 一. 映射文件的顶级元素 selec ...
- mybatis中resultType和resultMap的联系
在使用mybatis进行数据库连接操作时对于SQL语句返回结果的处理通常有两种方式,一种就是resultType另一种就是resultMap,下面说下我对这两者的认识和理解 比如,我们平时使用的单表查 ...
- MyBatis学习总结_13_Mybatis查询之resultMap和resultType区别
MyBatis的每一个查询映射的返回类型都是ResultMap,只是当我们提供的返回类型属性是resultType的时候,MyBatis对自动的给我们把对应的值赋给resultType所指定对象的属性 ...
- Mybatis源码分析--返回值ResultType和ResultMap
这一篇博客我们来介绍一下Mybatis执行sql语句返回的结果值的到实体对象的映射机制.首先ResultType和ResultMap的使用方式是不同的. ResultType的使用方式: result ...
- MyBatis学习总结_Mybatis查询之resultMap和resultType区别
MyBatis的每一个查询映射的返回类型都是ResultMap,只是当我们提供的返回类型属性是resultType的时候,MyBatis对自动的给我们把对应的值赋给resultType所指定对象的属性 ...
- [转]MyBatis中resultType与resultMap区别
MyBatis中关于resultType和resultMap的具体区别如下: MyBatis中在查询进行select映射的时候,返回类型可以用resultType,也可以用resultMap.resu ...
- Mybatis笔记四:Mybatis中的resultType和resultMap查询操作实例详解
resultType和resultMap只能有一个成立,resultType是直接表示返回类型的,而resultMap则是对外部ResultMap的引用,resultMap解决复杂查询是的映射问题.比 ...
随机推荐
- Educational Codeforces Round 129 (Rated for Div. 2) A-D
Educational Codeforces Round 129 (Rated for Div. 2) A-D A 题目 https://codeforces.com/contest/1681/pro ...
- FileNameFilter过滤器的使用和Lambda优化程序--IO概述(概念&分类)
FileNameFilter过滤器的使用和Lambda优化程序 public class Demo02Filter { public static void main(String[] args) { ...
- if else 还在用吗?
当我们在使用if else 的时候,你是否闻到代码的坏味道呢? 除非非常简单的逻辑,当我们在写一大坨if else的时候,就应该审视一下是否这样写合适呢?是否这一坨代码体现某一个业务语义呢?是否体现领 ...
- 【最全】CSS盒子(div)水平垂直居中居然还有这种方式
最全的CSS盒子(div)水平垂直居中布局,对CSS 布局掌握程度决定你在 Web 开发中的开发页面速度. 相对于屏幕 方法一:利用定位 <div class="box"&g ...
- Netty-如何写一个Http服务器
前言 动机 最近在学习Netty框架,发现Netty是支持Http协议的.加上以前看过Spring-MVC的源码,就想着二者能不能结合一下,整一个简易的web框架(PS:其实不是整,是抄) 效果 项目 ...
- 非root用户安装科学计算包blas、lapack和FFTW
一.安装FFTW 1.下载安装包 下载地址:http://www.fftw.org/download.html 2.编译安装 tar -zxvf fftw-3.3.10.tar.gz cd fftw ...
- Apache DolphinScheduler 1.3.8 发布
小伙伴们 Apache DolphinScheduler 1.3.8 发布 2021年9月7日,正式发布 在 1.3.8 版本中,我们在 Docker&k8s 这里做了许多优化,Docker ...
- Ansible yaml 剧本(傻瓜式)
优化ansible安装MySQL: Ansible部署MySQL编译安装 - xiao智 - 博客园 (cnblogs.com) Ansible yaml 剧本(傻瓜式): --- - hosts: ...
- 如何开发一款基于 vite+vue3 的在线表格系统(下)
在上篇内容中我们为大家分享了详细介绍Vue3和Vite的相关内容.在本篇中我们将从项目实战出发带大家了解Vite+Vue3 的在线表格系统的构建. 使用Vite初始化Vue3项目 在这里需要注意:根据 ...
- 基于bert_bilstm_crf的命名实体
前言 本文将介绍基于pytorch的bert_bilstm_crf进行命名实体识别,涵盖多个数据集.命名实体识别指的是从文本中提取出想要的实体,本文使用的标注方式是BIOES,例如,对于文本虞兔良先生 ...