三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

MyBatis的resultType和resultMap的区别

MyBatis的resultType和resultMap的区别

一、引言

在使用 MyBatis 进行数据库连接操作时,对于 SQL 语句返回结果的处理通常有两种方式:resultTyperesultMap。这两种方式各有其适用场景和特点,理解它们的区别对于编写高效、清晰的 MyBatis 映射文件至关重要。本文将详细介绍这两种结果映射方式,并结合实际代码示例,帮助你根据不同的查询需求做出合适的选择。

二、resultType:简单直接的映射

2.1 基本概念与使用

resultType是 MyBatis 中最直接的结果映射方式。当使用 resultType 时,SQL 查询出的字段名必须与 POJO(Plain Old Java Object)中的属性名完全一致(或遵循驼峰命名转换规则),MyBatis 会自动将查询结果映射到指定类型的对象中。

resultType 的值通常是 POJO 在项目中的全限定类名或别名。

2.2 适用场景与优缺点

适用场景:

  • 单表查询:查询的字段与 POJO 属性一一对应时,使用 resultType 最为合适。
  • 简单查询:查询结果不需要复杂的关联映射。

优点:

  • 配置简单,无需额外定义 resultMap。
  • 代码简洁,易于理解。

缺点:

  • 字段名必须严格匹配,灵活性较差。
  • 无法处理复杂的关联查询(如一对一、一对多)。

2.3 多表查询的变通处理

虽然 resultType 主要用于单表映射,但在多表连接查询时,也可以通过创建“组合 POJO”来变通使用:

  • 一对一查询:新建一个 POJO,包含两个表中需要查询的所有字段。通常做法是创建一个继承自主表 POJO 的类,并添加从表所需字段。
  • 一对多查询:若使用内连接,查询结果可能出现重复记录。此时需要在业务层(如 Service)中通过双重 for 循环进行去重和组装。

这种方式虽然可行,但会使得 POJO 设计变得复杂,且业务层逻辑繁重,因此对于复杂的关联查询,更推荐使用 resultMap。

三、resultMap:强大灵活的映射

3.1 基本概念与定义

resultMap是 MyBatis 中功能更强大的结果映射方式。它允许你在 mapper.xml 文件中显式地定义数据库字段与 Java 对象属性之间的映射关系,从而解除了字段名必须与属性名严格匹配的限制,并能够处理复杂的对象关联。

一个基本的 resultMap 定义如下:

<!-- 订单查询关联用户的 resultMap --> <!-- 将整个查询的结果映射到 cn.itcast.mybatis.po.Orders 中 --> <resultMap type="cn.itcast.mybatis.po.Orders" id="OrdersUserResultMap"> <!-- 配置映射的订单信息 --> <!-- id:指定查询列中的唯一标识,订单信息的唯一标识,如果有多个列组成唯一标识,配置多个id column:订单信息的唯一标识列 property:订单信息的唯一标识列所映射到 Orders 中哪个属性 --> <id column="id" property="id"/> <result column="user_id" property="userId"/> <result column="number" property="number"/> <result column="createtime" property="createtime"/> <result column="note" property="note"/> </resultMap>

3.2 处理一对一关联(association)

当查询涉及两个具有一对一关系的表时(如订单和用户),可以在主表的 POJO 中添加另一个表的 POJO 作为属性,然后在 resultMap 中使用<association>元素进行映射。

示例:查询订单及其关联的用户信息

<resultMap type="cn.itcast.mybatis.po.Orders" id="OrdersUserResultMap"> <!-- 订单基本信息映射 --> <id column="id" property="id"/> <result column="user_id" property="userId"/> <result column="number" property="number"/> <result column="createtime" property="createtime"/> <result column="note" property="note"/> <!-- 配置映射的关联的用户信息 --> <!-- association:用于映射关联查询单个对象的信息 property:要将关联查询的用户信息映射到 Orders 中哪个属性 --> <association property="user" javaType="cn.itcast.mybatis.po.User"> <!-- id:关联查询用户的唯一标识 column:指定唯一标识用户信息的列 property:映射到 user 的哪个属性 --> <id column="user_id" property="id"/> <result column="username" property="username"/> <result column="sex" property="sex"/> <result column="address" property="address"/> </association> </resultMap>

这样,查询结果会自动将用户信息封装到 Orders 对象的 user 属性中。

3.3 处理一对多关联(collection)

一对多关系(如一个订单对应多条订单明细)是实际开发中常见的场景。如果不对 SQL 语句进行特殊处理,由于一个订单对应多条明细,查询结果中订单信息会出现重复。

resultMap 的解决方案是:在主表 POJO 中添加一个 List 属性来存放从表的数据,并在 mapper.xml 中使用<collection>元素进行映射。

示例:查询订单及其所有订单明细

<!-- 订单及订单明细的 resultMap --> <!-- 使用 extends 继承,不用在中配置订单信息和用户信息的映射 --> <resultMap type="cn.itcast.mybatis.po.Orders" id="OrdersAndOrderDetailResultMap" extends="OrdersUserResultMap"> <!-- 订单信息 --> <!-- 用户信息 --> <!-- 使用 extends 继承,不用在中配置订单信息和用户信息的映射 --> <!-- 订单明细信息 一个订单关联查询出了多条明细,要使用 collection 进行映射 collection:对关联查询到多条记录映射到集合对象中 property:将关联查询到多条记录映射到 cn.itcast.mybatis.po.Orders 哪个属性 ofType:指定映射到 list 集合属性中 pojo 的类型 --> <collection property="orderdetails" ofType="cn.itcast.mybatis.po.Orderdetail"> <!-- id:订单明细唯一标识 property:要将订单明细的唯一标识映射到 cn.itcast.mybatis.po.Orderdetail 的哪个属性 --> <id column="orderdetail_id" property="id"/> <result column="items_id" property="itemsId"/> <result column="items_num" property="itemsNum"/> <result column="orders_id" property="ordersId"/> </collection> </resultMap>

通过这种方式,虽然一条订单信息对应多条订单明细,但由于将多条明细存储到了 List 集合中,查询后将不再出现重复的订单数据,达到了去重的效果。

四、resultType 与 resultMap 对比总结

对比项resultTyperesultMap
映射方式自动映射,字段名与属性名需一致手动映射,可自定义字段与属性的对应关系
配置复杂度简单,无需额外配置复杂,需显式定义映射关系
灵活性较低,受限于命名规范高,可处理复杂映射和关联
适用场景单表简单查询多表关联查询、复杂映射、字段名不一致
性能较高(自动映射)稍低(需解析映射配置)
代码可读性高(直观简单)取决于映射定义的清晰度

五、实践建议与选择策略

  1. 简单查询优先使用 resultType:对于单表查询或字段名与属性名完全匹配的场景,使用 resultType 可以让代码更简洁。
  2. 复杂关联必须使用 resultMap:涉及一对一、一对多关联查询时,resultMap 是唯一的选择。
  3. 考虑使用继承简化配置:如示例所示,通过 extends 属性继承已有的 resultMap,可以避免重复配置,提高可维护性。
  4. 注意性能影响:虽然 resultMap 功能强大,但复杂的嵌套映射可能会影响性能。在设计时应权衡功能需求与性能要求。
  5. 保持映射清晰:为每个 resultMap 添加清晰的注释,说明其用途和映射关系,便于团队协作和后期维护。

六、结语

resultType 和 resultMap 是 MyBatis 中处理查询结果的两种核心方式,它们各有优劣,适用于不同的场景。理解它们的原理和适用条件,能够帮助你在实际开发中做出更合理的技术选型,编写出既高效又易于维护的数据访问层代码。建议在项目初期就根据业务复杂度规划好映射策略,避免后期因映射混乱导致的维护困难。

← 返回列表