Mybatis之ResultMap、ResultType返回结果使用姿势
在使用mybatis进行数据库操作时,如果希望将返回结果映射为项目中定义的实体对象Entity时,ResultMap与ResultType就很重要了;它们两的主要区别在于ResultType指定指定实体对象,ResultMap则定义数据库字段与实体的映射关系
接下来通过简单的实例来看一下这两种的使用姿势
I. 环境配置
我们使用SpringBoot + Mybatis + MySql来搭建实例demo
•springboot: 2.2.0.RELEASE•mysql: 5.7.22
1. 项目配置
<dependencies> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.2.0</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency></dependencies>核心的依赖mybatis-spring-boot-starter,至于版本选择,到mvn仓库中,找最新的
另外一个不可获取的就是db配置信息,appliaction.yml
spring: datasource: url: jdbc:mysql://127.0.0.1:3306/story?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai username: root password:2. 数据库表
用于测试的数据库
CREATE TABLE `money` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `name` varchar(20) NOT NULL DEFAULT '' COMMENT '用户名', `money` int(26) NOT NULL DEFAULT '0' COMMENT '钱', `is_deleted` tinyint(1) NOT NULL DEFAULT '0', `create_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `update_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', PRIMARY KEY (`id`), KEY `name` (`name`)) ENGINE=InnoDB AUTO_INCREMENT=551 DEFAULT CHARSET=utf8mb4;II. ResultMap & ResultType介绍
1. 使用区别
ResultMap:
•当数据库的字段与定义的实体对象不一致时(如下划线转驼峰,命名不一致等)通过<ResultMap>标签来定义映射关系,然后在sql查询标签中,通过resultMap来指定
ResultType:
•db中的字段直接与实体对象进行映射时,选择ResultType,其value为实体类的全路径
2. 实例演示
注意上面的表结构,是以下划线的命名方式,接下来定义一个驼峰格式的实体类
@Data@NoArgsConstructor@AllArgsConstructorpublic class MoneyPo { private Integer id; private String name; private Long money; private Integer isDeleted; private Timestamp createAt; private Timestamp updateAt;}基于上面这个case,很明显当我们使用查询时,返回结果就需要做一个映射,此时就可以使用<ResultMap>方式
<resultMap id="BaseResultMap" type="com.git.hui.boot.mybatis.entity.MoneyPo"> <id column="id" property="id" jdbcType="INTEGER"/> <result column="name" property="name" jdbcType="VARCHAR"/> <result column="money" property="money" jdbcType="INTEGER"/> <result column="is_deleted" property="isDeleted" jdbcType="TINYINT"/> <result column="create_at" property="createAt" jdbcType="TIMESTAMP"/> <result column="update_at" property="updateAt" jdbcType="TIMESTAMP"/></resultMap><sql id="money_po"> id, name, money, is_deleted, create_at, update_at</sql><select id="queryByName" parameterType="java.lang.String" resultMap="BaseResultMap"> select * from money where `name` = #{name}</select>注意上面的select标签,通过resultMap来实现表字段与实体对象的转换关系(通过<resultMap>标签内的<result>来定义映射关系)
除了使用上面这种方式之外,也可以通过resultType来指定返回结果为Map,同样是可行的
<select id="queryMapsByName" parameterType="java.lang.String" resultType="java.util.HashMap"> select * from money where `name` = #{name}</select>对应的mapper接口内容如下
@Mapperpublic interface MoneyMapperV4 { /** * int类型,最终的sql中参数替换的也是int * @param name * @return */ List<MoneyPo> queryByName(@Param("name") String name); /** * 注意返回结果 * * @param name * @return */ List<HashMap<String, Object>> queryMapsByName(@Param("name") String name);}3. 测试验证
@Autowiredprivate MoneyMapperV4 moneyMapperV4;public void testResQuery() { List<MoneyPo> list = moneyMapperV4.queryByName("一灰灰blog"); System.out.println(list); List<HashMap<String, Object>> mapList = moneyMapperV4.queryMapsByName("一灰灰blog"); System.out.println(mapList);}输出结果如下
[MoneyPo(id=1, name=一灰灰blog, money=100, isDeleted=0, createAt=2019-04-18 17:01:40.0, updateAt=2019-04-18 17:01:40.0, cnt=null, bank=null)][{is_deleted=false, money=100, name=一灰灰blog, update_at=2019-04-18 17:01:40.0, id=1, create_at=2019-04-18 17:01:40.0}]请注意上面的输出,返回结果是Map时,key和db中的字段名完全一致
其次也可以从Mapper接口的返回定义上可以看出,虽然最终返回的是列表,但是我们定义的resultMap, resultType,都是对应的单个实体的映射关系
如何理解上面这句话呢?
•如果上面的sql改成只获取id,那么返回结果应该是定义为longe而不是List
<select id="queryIdByName" resultType="long"> select id from money where `name` = #{name}</select>对应的mapper接口如下
List<Long> queryIdByName(String name);4. 小结
ResultMap
•当希望实现sql返回的对象与项目中的实体类实现关联映射时,可以考虑通过resumtMap来实现
ResultType
•指定返回实体类型,可以是基础对象(long, int...) 也可以是Map,当指定一个具体的POJO时,db的表字段与pojo的field全名匹配映射
III. 不能错过的源码和相关知识点
0. 项目
•工程:https://github.com/liuyueyi/spring-boot-demo
•源码:https://github.com/liuyueyi/spring-boot-demo/tree/master/spring-boot/103-mybatis-xml
系列博文
- SpringBoot 系列教程 Mybatis+注解整合篇
- 「SpringBoot」Mybatis多数据源配置与使用
- 「SpringBoot Mybatis系列」MapperMapper接口与Sql绑定几种姿势
- SpringBoot系列 Mybatis 之自定义类型转换 TypeHandler
- SpringBoot + Mybatis系列之插件机制 Interceptor SpringBoot 系列教程 Mybatis+xml 整合篇
- 「SpringBoot + Mybatis系列」Mapper接口注册的几种方式
- 「SpringBoot」Mybatis-Plus多数据源配置 SpringBoot系列之Mybatis 之转义符的使用姿势
- SpringBoot系列Mybatis之参数传递的几种姿势
- SpringBoot Mybatis基于AOP 多数据源切换
- SpringBoot系列Mybatis之ResultMap、ResultType返回结果使用姿势
- SpringBoot 系列教程 MybatisPlus 整合篇
- SpringBoot系列之Mybatis传参类型如何确定
1. 微信公众号: 一灰灰Blog
尽信书则不如,以上内容,纯属一家之言,因个人能力有限,难免有疏漏和错误之处,如发现bug或者有更好的建议,欢迎批评指正,不吝感激
下面一灰灰的个人博客,记录所有学习和工作中的博文,欢迎大家前去逛逛
•一灰灰Blog个人博客 https://blog.hhui.top
•一灰灰Blog-Spring专题博客 http://spring.hhui.top