5

【DB系列】Mybatis之ResultMap、ResultType返回结果使用姿势

 3 years ago
source link: https://spring.hhui.top/spring-blog/2022/01/10/220110-Mybatis%E4%B9%8BResultMap%E3%80%81ResultType%E8%BF%94%E5%9B%9E%E7%BB%93%E6%9E%9C%E4%BD%BF%E7%94%A8%E5%A7%BF%E5%8A%BF/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

logo.jpg

【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);

ResultMap

  • 当希望实现sql返回的对象与项目中的实体类实现关联映射时,可以考虑通过resumtMap来实现

ResultType

  • 指定返回实体类型,可以是基础对象(long, int…) 也可以是Map,当指定一个具体的POJO时,db的表字段与pojo的field全名匹配映射

III. 不能错过的源码和相关知识点

系列博文:

1. 微信公众号: 一灰灰Blog

尽信书则不如,以上内容,纯属一家之言,因个人能力有限,难免有疏漏和错误之处,如发现bug或者有更好的建议,欢迎批评指正,不吝感激

下面一灰灰的个人博客,记录所有学习和工作中的博文,欢迎大家前去逛逛

一灰灰blog

打赏 如果觉得我的文章对您有帮助,请随意打赏。

分享到


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK