大厂Java面试题:MyBatis是中如何将结果集映射到Java持久化对象?都有哪些方式?有什么区别?

news2025/1/13 2:58:25

大家好,我是王有志。今天给大家带来的是一道来自京东的 MyBatis 面试题:MyBatis是中如何将结果集映射到Java持久化对象?都有哪些方式?有什么区别?

MyBatis 提供了两种实现结果集到 Java 持久化对象的映射方式:

  • 自动映射,不显式指定映射关系;
  • 主动映射,使用 resultTyp 或者 resultMap 指定映射关系。

通常在生产应用中,我们可以直接放弃使用自动映射这种方式,在数据库表中的字段与 Java 持久化对象中的字段是一一对应的场景下,且能够使用 MyBatis 插件“mapUnderscoreToCamelCase”实现映射,那么我们可以选择使用 resultType 属性进行配置,如果不能一一对应,或者不能通过 MyBatis 插件“mapUnderscoreToCamelCase”实现映射,以及映射关系较为复杂(例如:一对一关联,一对多关联登)的场景下,我们应该使用 resultMap 元素定义映射关系。

自动映射

自动映射指的是不显式指定 resultType 或 reusltMap,让 MyBatis 尝试自动根据查询结果的列名与 Java 持久化对象进行匹配进行映射,这需要保证数据库表中的字段名与 Java 持久化对象的字段名一致,也可以通过为查询语句中的字段取别名,或者是使用 MyBatis 插件“mapUnderscoreToCamelCase”的方式实现自动映射

下面我们举个例子。

定义数据库表 order_item,代码如下:

create table order_item (
  item_id         int            not null comment '订单商品表主键' primary key,
  order_id        int            not null comment '订单表主键',
  commodity_id    int            not null comment '商品表主键',
  commodity_price decimal(18, 2) not null comment '商品价格',
  commodity_count int            not null comment '商品数量'
) comment '订单明细表';

定义 Java 持久化对象 OrderItemDO,代码如下:

public class OrderItemDO {

  private Integer itemId;

  private Integer orderId;

  private Integer commodityId;

  private BigDecimal commodityPrice;

  private Integer commodityCount;
}

定义 OrderItemMapper 接口中的方法,代码如下:

public interface OrderItemMapper {
    List<OrderItemDO> selectByAutoMap();
}

定义 OrderItemMapper 映射器中的 SQL 语句,代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.wyz.mapper.OrderItemMapper">
  <select id="selectByAutoMap">
    select item_id as itemId,
           order_id as orderId,
           commodity_id as commodityId,
           commodity_price as commodityPrice,
           commodity_count as commodityCount
    from order_item
  </select>
</mapper>

注意,此时 OrderItemMapper 接口的中方法可能会报错,提示如下:

Result type not match for select id=“selectByAutoMap” srcType: targetType: com.wyz.entity.OrderItemDO

针对于这个报错,我们直接忽略就可以了。

最后来写单元测试,代码如下:

public void testSelectByAutoMap() throws IOException {
Reader mysqlReader = Resources.getResourceAsReader("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(mysqlReader);
SqlSession sqlSession = sqlSessionFactory.openSession();
OrderItemMapper orderItemMapper = sqlSession.getMapper(OrderItemMapper.class);

List<OrderItemDO> orderItems = orderItemMapper.selectByAutoMap();
System.out.println(JSON.toJSONString(orderItems, JSONWriter.Feature.PrettyFormat));
}

执行单元测试,可以看到控制台正常输出了查询到的数据。

这种方式是在 MyBatis 应用程序构建 MappedStatement 时通过反射获取 OrderItemMapper 接口中的方法,解析方法返回值的方式来获取到结果集映射的 Java 持久化对象的,部分源码如下所示:

图中源码做了大量删减,重点关注下调用链路即可,高亮的部分就是通过反射获取数据集映射的 Java 持久化对象类型的部分。因为需要做额外的工作,并且使用到反射技术,因此在效率上较差,不建议使用这种方式。

主动映射

主动映射可以通过 select 元素中的 resultType 属性定义,也可以通过 resultMap 元素结合 select 元素的 resultMap 属性定义。

使用 reusltType 进行映射

修改 OrderItemMapper 映射器中的 SQL 语句,为其添加 resultType 属性,代码如下:

<select id="selectByAutoMap" resultType="com.wyz.entity.OrderItemDO">
  select item_id as itemId,
         order_id as orderId,
         commodity_id as commodityId,
         commodity_price as commodityPrice,
         commodity_count as commodityCount
  from order_item
</select>

再次执行单元测试,可以看到控制台能够正常输出查询结果。

这种方式与自动映射基本一致,只不过我们指定了 reusltType 的类型,MyBatis 只需要根据 resultType 的配置反射出相应的类型即可,而不需要反射出方法的返回值。同样的,使用 resultType 也需要保证数据库表中的字段名与 Java 持久化对象中的字段名完全一致,当然了,同样也可以通过为查询语句中的字段起别名,或者是使用 MyBatis 的插件“mapUnderscoreToCamelCase”解决。

这种方式 MyBatis 会直接读取 reusltType 的配置,并通过类型别名注册器 TypeAliasRegistry 去解析出配置对应的类名。

使用 resultMap 进行映射

使用 resulttMap 元素可以定义数据库表中的字段名与 Java 持久化对象中的字段名的映射器关系,因为 resultMap 元素强大的功能,它可以处理很多复杂的场景,具体用法可以参考我在掘金专栏中的文章:《MyBatis映射器:一对一关联查询》和《MyBatis映射器:一对多关联查询》。

下面我们使用 resulttMap 元素定义映射关系,代码如下:

<resultMap id="BaseResultMap" type="com.wyz.entity.OrderItemDO">
  <id property="itemId" column="item_id" jdbcType="INTEGER"/>
  <result property="orderId" column="order_id" jdbcType="INTEGER"/>
  <result property="commodityId" column="commodity_id" jdbcType="INTEGER"/>
  <result property="commodityPrice" column="commodity_price" jdbcType="DECIMAL"/>
  <result property="commodityCount" column="commodity_count" jdbcType="INTEGER"/>
</resultMap>

修改 OrderItemMapper 映射器中的 SQL 语句,为其添加 resultMap 属性,代码如下:

<select id="selectByAutoMap" resultMap="BaseResultMap">
  select item_id,
         order_id,
         commodity_id,
         commodity_price,
         commodity_count
  from order_item
</select>

最后再来执行单元测试,可以看到控制台依旧可以正常输出结果。

使用 reusltMap 元素的优点是,灵活性高,能够适应复杂的场景,并且使用 resultMap 元素的可读性更好,能够清晰直观的看到数据库中表的字段与 Java 持久化对象中字段的映射关系,如果硬要说缺点,也只能是学习成本高(相对来说),配置及相对复杂


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1819864.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

springbot 界面美观的超市收银管理系统。

springbot 界面美观的超市收银管理系统。 功能&#xff1a;登录&#xff0c;用户管理&#xff0c;权限菜单管理&#xff0c;首页订单&#xff0c;收入&#xff0c;用户统计&#xff0c; 收银台&#xff0c;销售账单&#xff0c;库存管理&#xff0c;商品分类&#xff0c;供应…

一张图读懂天然气气源

一张图读懂天然气气源

Dev-C++安装及使用

起因&#xff1a;我写的游戏都是用DEV-C 写的&#xff1b; Dev的介绍&#xff1a; Dev-C&#xff08;或者叫做 Dev-Cpp&#xff09;是 Windows 环境下的一个轻量级 C/C 集成开发环境&#xff08;IDE&#xff09;。非常适合于C/C语言初学者使用。 它是一款自由软件&#xff0c;…

npm login 或者 npm adduser 之后 遇见 Public registration is not allowed

npm login 或者 npm adduser 之后 遇见 Public registration is not allowed 其实是因为npm镜像地址有问题 使用下方指令 将镜像切回即可正确完成登录操作 npm config set registry https://registry.npmjs.org/ 今天就总结到这里啦&#xff01; 后续会不定时更新哦&#xff…

Linux Debian12使用podman安装xss-labs靶场环境

一、xss-labs简介 xss-labs靶场是一个专门用于学习和练习跨站脚本攻击&#xff08;XSS&#xff09;技术的在线平台。它提供了一系列的实验场景和演示&#xff0c;帮助安全研究人员、开发人员和安全爱好者深入了解XSS攻击的原理和防御方法。 二、安装podman环境 Linux Debian…

计算机msvcp100.dll丢失怎么办,分享5种亲测有效的解决方法

电脑已经成为我们生活中不可或缺的一部分。然而&#xff0c;在使用电脑的过程中&#xff0c;我们常常会遇到一些问题&#xff0c;其中之一就是电脑提示缺失msvcp100.dll。这个问题可能会让我们感到困惑和烦恼&#xff0c;但是只要我们了解其原因并采取相应的解决方法&#xff0…

FPGA+金融|硬件行情加速系统 打造极速交易场景

会议时间&#xff1a;2024年06月20日&#xff08;周四&#xff09;下午13:50 FPGA金融|硬件行情加速系统 打造极速交易场景_中科亿海微_芯有灵犀 智创未来

6.12ctf练习

[西湖论剑 2022]Node Magical Login 源码在这里&#xff1a;GitHub - CTF-Archives/2022-xhlj-web-node_magical_login: A web challenge in 2022 西湖论剑大赛打开 打开环境是个登录框&#xff0c;先进行了扫描和抓包都没有看见什么有价值的东西&#xff0c;看源码 大致连接…

因数与倍数 初级题目

最近又来更题了。这一次是《第三单元 因数与倍数第一部分》的初级题目。 参考答案见文尾 参考答案&#xff1a; CBDAABCBBACCCCCBCDCC

Airtest 使用指南

Airtest 介绍 准备工作 AirtestIDE 安装与启动: https://airtest.doc.io.netease.com/IDEdocs/getting_started/AirtestIDE_install/ 电脑端的准备工作完成后,对于手机端只需要打开允许USB调试,当首次运行时会提示安装PocoService,同意即可。 界面介绍

仲恺ZK——信计专业《软件体系结构》24年试卷回忆

以下是我在总结的复习内容&#xff0c;有需要可以参考借鉴一下。我的主页还有另外一篇复习总结《仲恺ZK——信计专业《软件体系结构》&#xff0c;两者结合起来复习&#xff0c;帮助你轻松过考试&#x1f60a;。总的来说&#xff0c;考试不会太难&#xff0c;只要你了解了各类设…

2024 Java 异常—面试常见问题

目录 一、异常的分类 二、throw和throws都是异常处理的关键字&#xff0c;二者区别。 三、try-catch-finally 中&#xff0c;如果 catch 中 return 了&#xff0c;finally 还会执行吗&#xff1f; 四、try-catch-finally 中哪个部分可以省略&#xff1f; 五、常见的 Runti…

如何基于Nginx配置代理服务器实现邮件告警

当代企业信息化系统建设中&#xff0c;将内网与公网进行隔离是一种非常常见的措施&#xff0c;它可以有效保护企业内部数据不被外泄&#xff0c;有助于企业构建一个更加安全的网络环境&#xff0c;保护企业资产和用户隐私。但另一方面&#xff0c;内网与公网隔离也会带来一些问…

本地无法连接linux上的MariaDB数据库

使用mysql -u root -p 输入密码&#xff1a; 进去之后没有user表&#xff0c;无法改user、host等信息。

安装Pygame

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 Pygame是跨平台的Python模块&#xff0c;专为电子游戏设计&#xff08;包含图像、声音&#xff09;&#xff0c;创建在SDL&#xff08;Simple Direct…

QT day01

思维导图 QT编程 实现一个账号登录界面 代码&#xff1a; myweidget.h #ifndef MYWEIDGET_H #define MYWEIDGET_H#include <QWidget> #include <QIcon> //图标类 #include <QLineEdit> //行编辑器类 #include <QLabel> //标签类 #…

GROUP_CONCAT

– select 中可以查询的是 GROUP BY 后的&#xff0c;以及这类 MAX() GROUP_CONCAT(expr) 等 select su.* ,sd.dept_name deptName , sp.post_name postName ,GROUP_CONCAT(sr.role_name),GROUP_CONCAT(sr.id) from sys_user su LEFT JOIN sys_dept sd on su.dept_no sd.dept_…

QtScrcpy最出色的C++开源手机投屏控制软件

QtScrcpy是一款开源的跨平台屏幕录制和投屏工具 基本概述&#xff1a; 它基于Android的ADB&#xff08;Android Debug Bridge&#xff09;和Electron框架&#xff0c;为用户提供了简洁且功能强大的用户界面。 支持平台&#xff1a; QtScrcpy支持Windows、macOS和Linux三大…

Vue配置项之directives

Directives 首先说明一下&#xff0c;本人是前端小学生级别的菜鸡&#xff0c;吐槽的话请口下留情&#xff0c;在评论区指出错误或者补充不足&#xff0c;我会很喜欢&#xff0c;互喷不会进步&#xff0c;相互指点才会。。。。谢谢大家啦 目录 Directives 目录自己定义官网简…

摄影构图:如何处理对焦、快门、光圈、ISO 以及拍摄方式

写在前面 博文内容涉及摄影对焦模式、快门速度、光圈、ISO以及拍摄方式的简单介绍《高品质摄影全流程解析》 读书笔记整理理解不足小伙伴帮忙指正 &#x1f603; 生活加油 99%的焦虑都来自于虚度时间和没有好好做事&#xff0c;所以唯一的解决办法就是行动起来&#xff0c;认真…