【DB系列】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 @AllArgsConstructor public 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接口内容如下
@Mapper public 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. 测试验证
@Autowired private 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. 项目
- 工程: http://github.com/liuyueyi/spring-boot-demo
- 源码: http://github.com/liuyueyi/spring-boot-demo/tree/master/spring-boot/103-mybatis-xml
系列博文:
- 【DB系列】Mybatis系列教程之CURD基本使用姿势
- 【DB系列】Mybatis系列教程之CURD基本使用姿势-注解篇
- 【DB系列】Mybatis之参数传递的几种姿势
- 【DB系列】Mybatis之转义符的使用姿势
- 【DB系列】Mybatis之传参类型如何确定
- 【DB系列】Mybatis之ParameterMap、ParameterType传参类型指定使用姿势
1. 微信公众号: 一灰灰Blog
尽信书则不如,以上内容,纯属一家之言,因个人能力有限,难免有疏漏和错误之处,如发现bug或者有更好的建议,欢迎批评指正,不吝感激
下面一灰灰的个人博客,记录所有学习和工作中的博文,欢迎大家前去逛逛
- 一灰灰Blog个人博客 http://blog.hhui.top
- 一灰灰Blog-Spring专题博客 http://spring.hhui.top
打赏 如果觉得我的文章对您有帮助,请随意打赏。
- 【WEB系列】内嵌Tomcat配置Accesslog日志文件生成位置源码探索
- 【搜索系列】ES查询常用实例演示
- 【搜索系列】ES文档基本操作CURD实例演示
- 【搜索系列】ES基本项目搭建
- Nosql存储系统-集群工作原理
- 实例演示,带你了解终端神器ncat
- Redis:你真的会Redis么,一文告诉你如何学习
- 常用设计模式汇总,告诉你如何学习设计模式
- 微服务网关:从对比到选型,由理论到实践
- 【WEB系列】从0到1实现自定义web参数映射器
- SpringBoot系列Mybatis之批量插入的几种姿势
- SpringBoot系列Mybatis之ResultMap、ResultType返回结果使用姿势
- 【DB系列】Mybatis之批量插入的几种姿势
- 【DB系列】Mybatis之ResultMap、ResultType返回结果使用姿势
- 【中间件】Prometheus基于AOP实现埋点采集上报
- JDNI注入:RMI之绕过trustURLCodebase配置的注入实例演示三
- JDNI注入:RMI Reference引起的注入case二
- JDNI注入:RMI基本知识点介绍一
- JavaFun | 实现图片转字符输出示例demo
- JavaFun | 基于Java实现Gif图转字符动图