当前位置: 首页 > article >正文

MyBatis 高频八股文:从 Mapper 到缓存,一篇搞懂常见面试题

前言MyBatis 是 Java 后端开发中非常常用的持久层框架主要负责 Java 程序和数据库之间的数据交互。在 Spring Boot 项目中我们经常会用 MyBatis 或 MyBatis-Plus 来操作 MySQL。面试中MyBatis 常见问题包括MyBatis 是什么#{} 和 ${} 有什么区别MyBatis 如何防止 SQL 注入MyBatis 一级缓存和二级缓存是什么Mapper 接口为什么不需要实现类MyBatis 动态 SQL 怎么写MyBatis 和 Hibernate 有什么区别MyBatis 分页怎么实现这篇文章整理一份 MyBatis 高频八股文适合初学者和准备面试的同学快速复习。1. MyBatis 是什么MyBatis 是一个优秀的持久层框架。它主要用于简化 Java 操作数据库的过程。传统 JDBC 操作数据库时需要手动获取连接 创建 Statement 执行 SQL 处理结果集 关闭资源代码比较繁琐。MyBatis 帮我们封装了这些重复操作开发者只需要关注SQL 怎么写 参数怎么传 结果怎么映射简单来说MyBatis 是一个半自动 ORM 框架用来简化数据库操作。2. 什么是 ORMORM 全称是 Object Relational Mapping中文叫对象关系映射。它的作用是把 Java 对象和数据库表建立映射关系。比如数据库中有一张用户表userJava 中有一个实体类public class User { private Long id; private String username; private Integer age; }ORM 框架可以帮助我们把数据库中的一行记录映射成 Java 对象。MyBatis 属于半自动 ORM因为 SQL 通常需要开发者自己写。3. MyBatis 的优点有哪些MyBatis 常见优点SQL 写在 XML 或注解中灵活性高。封装了 JDBC减少重复代码。支持动态 SQL。支持结果映射。学习成本相对较低。方便进行 SQL 优化。和 Spring Boot 整合方便。相比全自动 ORMMyBatis 更适合复杂 SQL 场景。4. MyBatis 和 JDBC 有什么区别对比项JDBCMyBatisSQL 编写写在 Java 代码中写在 XML 或注解中参数处理手动设置自动处理结果集处理手动封装自动映射资源关闭手动关闭框架管理开发效率较低较高JDBC 更底层MyBatis 是对 JDBC 的封装。5. MyBatis 核心组件有哪些MyBatis 核心组件主要有SqlSessionFactoryBuilder SqlSessionFactory SqlSession Executor MappedStatement Mapper简单理解SqlSessionFactoryBuilder用于构建 SqlSessionFactory。SqlSessionFactory用于创建 SqlSession。SqlSession执行 SQL 的核心对象。Executor真正执行 SQL 的执行器。MappedStatement封装 SQL 信息。Mapper我们写的数据库操作接口。实际开发中Spring Boot 会帮我们管理很多对象。6. MyBatis 执行流程是什么MyBatis 执行 SQL 的大致流程读取 MyBatis 配置文件。加载 Mapper XML 文件。创建 SqlSessionFactory。创建 SqlSession。通过 Mapper 代理对象调用方法。找到对应的 SQL 语句。设置 SQL 参数。执行 SQL。封装结果集。返回 Java 对象。简单总结Mapper 方法调用后MyBatis 会根据方法找到对应 SQL然后执行并把结果映射成对象。7. Mapper 接口为什么不需要实现类因为 MyBatis 会为 Mapper 接口创建动态代理对象。我们只需要定义接口public interface UserMapper { User selectById(Long id); }然后在 XML 中写对应 SQLselect idselectById resultTypeUser select * from user where id #{id} /selectMyBatis 会根据接口方法名和 XML 中的 SQL id 进行绑定。调用 Mapper 方法时本质上调用的是 MyBatis 生成的代理对象。8. #{} 和 ${} 有什么区别这是 MyBatis 高频面试题。#{}#{} 是预编译占位符。底层使用的是 PreparedStatement。例如select * from user where id #{id}会被处理成select * from user where id ?可以防止 SQL 注入。${}${} 是字符串拼接。例如select * from user order by ${column}它会直接把参数拼接到 SQL 中。如果参数不可信容易产生 SQL 注入风险。简单总结#{} 是预编译安全${} 是字符串拼接不安全。9. MyBatis 如何防止 SQL 注入MyBatis 推荐使用#{}因为 #{} 会使用预编译参数用户输入不会直接拼接到 SQL 中。例如select idselectByName resultTypeUser select * from user where username #{username} /select这样可以避免用户输入恶意 SQL。但是如果使用 ${}select * from user where username ${username}就可能存在 SQL 注入风险。所以实际开发中能用 #{} 就不要用 ${}。10. ${} 一般用在什么场景${} 虽然有风险但有些场景必须使用。比如动态表名、动态字段名、排序字段select * from ${tableName}order by ${column}因为表名和字段名不能用预编译参数替代。但是使用 ${} 时一定要做白名单校验。例如排序字段只能允许id create_time username不能直接相信前端传来的参数。11. resultType 和 resultMap 有什么区别resultTyperesultType 用于简单映射。当数据库字段名和 Java 属性名能对应上时可以直接使用。select idselectById resultTypeUser select id, username, age from user where id #{id} /selectresultMapresultMap 用于复杂映射。比如字段名和属性名不一致或者一对一、一对多查询。resultMap iduserMap typeUser id propertyid columnid/ result propertyuserName columnuser_name/ /resultMap简单总结简单映射用 resultType复杂映射用 resultMap。12. 数据库字段名和 Java 属性名不一致怎么办比如数据库字段是user_nameJava 属性是private String userName;解决方式有几种使用别名select user_name as userName from user使用 resultMapresult propertyuserName columnuser_name/开启驼峰映射mybatis: configuration: map-underscore-to-camel-case: true开启后user_name 可以自动映射成 userName。13. MyBatis 动态 SQL 是什么动态 SQL 指的是根据不同条件生成不同 SQL。比如查询用户时用户名、年龄、状态都可能不是必填。MyBatis 提供了很多动态 SQL 标签if where set trim choose when otherwise foreach动态 SQL 可以减少手动拼接 SQL 的麻烦。14. if 标签怎么用if 用于条件判断。select idselectUser resultTypeUser select * from user where 1 1 if testusername ! null and username ! and username #{username} /if if testage ! null and age #{age} /if /select如果 username 不为空就拼接 username 条件。如果 age 不为空就拼接 age 条件。15. where 标签有什么作用where 标签会自动处理 SQL 中的 where 和多余的 and。select idselectUser resultTypeUser select * from user where if testusername ! null and username ! and username #{username} /if if testage ! null and age #{age} /if /where /select如果没有任何条件where 不会生成。如果第一个条件前面有 and它会自动去掉。16. foreach 标签有什么作用foreach 常用于批量操作或 in 查询。例如根据多个 id 查询用户select idselectByIds resultTypeUser select * from user where id in foreach collectionids itemid open( separator, close) #{id} /foreach /select生成的 SQL 类似select * from user where id in (1,2,3)17. MyBatis 如何实现分页常见分页方式有两种使用 limitselect * from user limit #{offset}, #{pageSize}使用分页插件实际项目中常用PageHelper MyBatis-Plus 分页插件例如 PageHelperPageHelper.startPage(pageNum, pageSize); ListUser list userMapper.selectList();分页插件底层通常会拦截 SQL然后自动拼接分页语句。18. MyBatis 插件原理是什么MyBatis 插件本质上是拦截器。它可以拦截 MyBatis 中的部分核心对象方法例如Executor StatementHandler ParameterHandler ResultSetHandler常见插件功能分页 SQL 日志 性能监控 权限控制 数据脱敏分页插件就是通过拦截 SQL 执行过程修改 SQL 来实现分页。19. MyBatis 一级缓存是什么一级缓存是 SqlSession 级别的缓存。默认开启。同一个 SqlSession 中执行相同查询第二次可以直接从缓存中获取结果不再查询数据库。例如User user1 mapper.selectById(1L); User user2 mapper.selectById(1L);如果在同一个 SqlSession 中第二次查询可能会走一级缓存。但是如果执行了增删改操作一级缓存会被清空。20. MyBatis 二级缓存是什么二级缓存是 Mapper 级别的缓存。多个 SqlSession 可以共享同一个 Mapper 的二级缓存。二级缓存默认不开启需要手动配置。开启方式cache/还需要实体类支持序列化。不过实际项目中MyBatis 二级缓存用得不多。因为它容易带来数据一致性问题。实际开发中更常用 Redis 作为缓存。21. 一级缓存和二级缓存有什么区别对比项一级缓存二级缓存级别SqlSession 级别Mapper 级别是否默认开启默认开启默认关闭作用范围同一个 SqlSession多个 SqlSession实际使用默认存在较少使用简单总结一级缓存是 SqlSession 级别二级缓存是 Mapper 级别。22. MyBatis 延迟加载是什么延迟加载也叫懒加载。它指的是需要用到关联对象时才去查询数据库。比如查询用户时不一定马上查询用户订单。只有调用user.getOrders()时才查询订单数据。延迟加载可以减少不必要的数据库查询。但是如果使用不当也可能产生很多额外 SQL。23. MyBatis 一对一和一对多怎么处理MyBatis 可以使用 resultMap 处理关联关系。一对一使用association例如用户对应一个身份证信息。一对多使用collection例如一个用户有多个订单。简单记association一对一 collection一对多24. MyBatis 批量插入怎么写可以使用 foreach。insert idinsertBatch insert into user(username, age) values foreach collectionlist itemuser separator, (#{user.username}, #{user.age}) /foreach /insert这样可以一次插入多条数据。相比循环一条条插入批量插入效率更高。25. MyBatis 和 Hibernate 有什么区别对比项MyBatisHibernate类型半自动 ORM全自动 ORMSQL需要自己写自动生成较多灵活性高相对较低学习成本较低较高SQL 优化方便相对不直观适合场景复杂 SQL标准 ORM 场景简单回答MyBatis 更灵活适合复杂 SQLHibernate 自动化程度更高但 SQL 可控性较弱。国内 Java 后端项目中MyBatis 使用非常广泛。26. MyBatis 和 MyBatis-Plus 有什么区别MyBatis-Plus 是 MyBatis 的增强工具。它不是替代 MyBatis而是在 MyBatis 基础上增强。MyBatis-Plus 提供了很多常用功能通用 CRUD 条件构造器 分页插件 代码生成器 逻辑删除 自动填充 乐观锁插件使用 MyBatis-Plus 后很多简单 CRUD 不需要再手写 SQL。例如userMapper.selectById(1L); userMapper.insert(user); userMapper.updateById(user);简单总结MyBatis-Plus 是 MyBatis 的增强版可以提高开发效率。27. MyBatis-Plus 的 Wrapper 是什么Wrapper 是 MyBatis-Plus 提供的条件构造器。它可以用 Java 代码拼接查询条件。例如LambdaQueryWrapperUser wrapper new LambdaQueryWrapper(); wrapper.eq(User::getStatus, 1) .like(User::getUsername, zhang); ListUser list userMapper.selectList(wrapper);这样可以避免手写简单 SQL。常见 Wrapper 有QueryWrapper LambdaQueryWrapper UpdateWrapper LambdaUpdateWrapper实际开发中更推荐使用 LambdaQueryWrapper因为它可以避免字段名写错。28. MyBatis 常见注解有哪些常见注解包括Mapper Param Select Insert Update DeleteMapper标记 Mapper 接口。Param给参数命名。User selectByNameAndAge(Param(name) String name, Param(age) Integer age);Select直接在注解中写查询 SQL。Select(select * from user where id #{id}) User selectById(Long id);简单 SQL 可以用注解复杂 SQL 更推荐写在 XML 中。29. Param 注解有什么作用Param 用于给 Mapper 方法参数命名。例如User selectUser(Param(username) String username, Param(age) Integer age);XML 中可以这样使用select * from user where username #{username} and age #{age}如果方法有多个参数建议加上 Param避免参数名绑定出问题。30. MyBatis 面试怎么回答更稳回答 MyBatis 问题时可以按照是什么 为什么 怎么用 注意点比如问“#{} 和 ${} 有什么区别”可以这样回答#{} 是预编译占位符底层使用 PreparedStatement会把参数作为值处理可以防止 SQL 注入。${} 是字符串拼接会直接把参数拼接到 SQL 中存在 SQL 注入风险。一般能用 #{} 就不用 ${}只有动态表名、字段名、排序字段这类场景才会用 ${}并且要做白名单校验。再比如问“Mapper 接口为什么不需要实现类”可以这样回答因为 MyBatis 会为 Mapper 接口创建动态代理对象。调用 Mapper 方法时代理对象会根据接口全限定名和方法名找到对应的 MappedStatement也就是 XML 中配置的 SQL然后执行 SQL 并封装结果返回。总结MyBatis 是 Java 后端项目中非常常用的持久层框架面试高频内容主要包括MyBatis 基本概念 Mapper 动态代理 #{} 和 ${} SQL 注入 resultType 和 resultMap 动态 SQL 分页插件 一级缓存和二级缓存 延迟加载 MyBatis-Plus其中最重要的是MyBatis 是什么。#{} 和 ${} 的区别。Mapper 接口为什么不需要实现类。resultType 和 resultMap 的区别。动态 SQL 怎么写。一级缓存和二级缓存的区别。MyBatis 和 MyBatis-Plus 的区别。如果是初学者建议先把 MyBatis 的基本 CRUD、动态 SQL、结果映射搞清楚再去结合 Spring Boot 做一个完整项目。这样面试时不只是会背概念也能结合实际开发场景回答。

相关文章:

MyBatis 高频八股文:从 Mapper 到缓存,一篇搞懂常见面试题

前言MyBatis 是 Java 后端开发中非常常用的持久层框架,主要负责 Java 程序和数据库之间的数据交互。在 Spring Boot 项目中,我们经常会用 MyBatis 或 MyBatis-Plus 来操作 MySQL。面试中,MyBatis 常见问题包括:MyBatis 是什么&…...

AutoJS Pro9.3最新文档详解与入门教程

AutoJS Pro9.3最新文档详解与入门教程 关键词:AutoJS Pro9.3、AutoJS脚本开发、安卓自动化、AutoJS文档、AutoJS入门、AutoJS教程、手机自动化脚本 前言 最近在研究安卓自动化的时候,我重新把 AutoJS Pro 拿出来深度玩了一遍。以前用的还是比较旧的版本…...

特斯拉Model 3/Y CAN总线数据采集终极指南:5分钟掌握车辆系统监控

特斯拉Model 3/Y CAN总线数据采集终极指南:5分钟掌握车辆系统监控 【免费下载链接】model3dbc DBC file for Tesla Model 3 CAN messages 项目地址: https://gitcode.com/gh_mirrors/mo/model3dbc 想要深入了解特斯拉Model 3和Model Y的车辆内部通讯系统吗&a…...

深度解析socat-windows:构建Windows网络数据管道的架构与实践

深度解析socat-windows:构建Windows网络数据管道的架构与实践 【免费下载链接】socat-windows unofficial windows build of socat http://www.dest-unreach.org/socat/ 项目地址: https://gitcode.com/gh_mirrors/so/socat-windows 当你需要在Windows环境中…...

3203黄大年茶思屋榜文保姆级全落地解法「32期3题」量子启发式算法|大规模百万节点图平衡最小分割优化

03华夏之光永存・开源:黄大年茶思屋榜文保姆级全落地解法「32期3题」 【题目通用标题】 量子启发式算法|大规模百万节点图平衡最小分割优化 (前20% 干货区・免费可见) 核心结论先行(上机可跑、全参数开源、零修改直接用) 本题所属大规模图计算、组合优化、量子启发式…...

linux kernel CONFIG_KCMP解析

CONFIG_KCMP 是 Linux 内核 5.12 新增的独立开关,用于启用 kcmp () 系统调用,核心作用是让用户态安全地比对两个进程是否共享内核资源(FD、内存、信号等),典型用于容器 / CRIU 热迁移、调试与安全审计。下面从配置、系…...

copilot学生认证按键无法点击

万能的网友大佬们,谁知道这个绿色按键怎么变成灰色了无法再认证了呀呜呜呜...

AI原生OPC项目路演实录分享

AI北纬社区首期OPC加速营的路演在节前顺利举行。项目是从100多个报名中优中选优筛选出来的,录取率不到30%。学员不乏来自国内外知名高校的硕博人才和头部互联网大厂的资深大佬。我们在现场看完了全部项目。看之前以为会看到很多"AIX"的故事,看…...

怎么配置中转站,稳定的爽用gpt 5.5,附cc switch + codex 配置教程

想用gpt5.5,但翻墙太麻烦,没有境外信用卡,价格太高,这个时候选择中转站就成了不二的选择,下面来介绍下怎么配置中转站。 一、注册账号 地址:AI API Gateway 输入自己的账号密码 兑换菜单可以购买套餐、购…...

用Python 和 java 写 10 道题

1.已知1、1、2、3、5、8、13......就是从第三项开始,每一项等于前两项之和。求第100项。python写a,b 1,1 #第一项和第二项 for _ in range(3,101): #从第3项计算到第100项,需循环98次(前两项已有)a,b b,ab #a 变成前一项 b 变成新的当前…...

C#基础10

分线程通常指的是如何开启一个独立于主程序(主线程)之外的执行流,让程序能够“一心二用”。比如,主界面保持流畅响应用户点击,而后台线程在默默下载大文件或处理复杂计算。从最基础的底层实现到现代的高级写法&#xf…...

Apple MLX框架下的脉冲神经网络(SNN)实现与优化

1. 项目概述:mlx-snn的诞生背景与核心价值在深度学习领域,脉冲神经网络(SNN)正逐渐成为继传统人工神经网络(ANN)和卷积神经网络(CNN)之后的"第三代神经网络"。与常规神经网…...

[特殊字符] 数组中的多数元素 II:Boyer-Moore投票算法详解

问题描述 给定一个包含 n 个整数的数组 arr[],找出所有出现次数超过 floor(n/3) 次的数组元素。 注意:返回的多数元素数组应该是排序的。 示例: 输入:arr[] [2, 2, 3, 1, 3, 2, 1, 1] 输出:[1, 2] 解释&#xff1a…...

开源情报实战指南:从工具到体系的OSINT方法论与自动化实践

1. 项目概述:一个开源情报收集的实战指南最近在整理自己的安全工具箱时,发现很多朋友对开源情报(OSINT)的实战应用很感兴趣,但往往止步于理论,或者被海量的工具和碎片化的信息淹没。恰好,我在Gi…...

微信福音:2345清理王微信专清功能介绍

现在大家用微信的时间越来越长,微信里的缓存也越攒越多,经常是好几个G,特别占空间。但是想清理又怕删错重要数据,不敢随便动手。这时候,微信专清功能就显得尤为重要。2345清理王的微信专清功能,完美解决了这…...

Termi AI:基于Electron的智能桌面开发伴侣,集成Vite预览与AI编程助手

1. 项目概述:一个集成了AI助手的桌面开发伴侣如果你和我一样,每天大部分时间都泡在终端和编辑器里,那你肯定也幻想过:能不能有一个工具,能把我的项目实时预览和AI编程助手无缝地“焊”在一起?不用在浏览器、…...

AI编程助手集成Codex CLI:MCP协议实现智能代码分析与本地模型部署

1. 项目概述:连接AI与代码的智能桥梁 如果你和我一样,日常开发中频繁使用 Claude 或 Cursor 这类AI编程助手,同时又深度依赖 OpenAI Codex CLI 进行代码分析和重构,那么你很可能面临一个效率瓶颈:如何在不同的工具之间…...

【EAI(企业应用集成)工具】Asteria warp簡単紹介(アステリア ワープ)

目录 ■前言 ■Asteria warp簡単紹介 ■ASTERIA Warpとは ■ASTERIA Warp 命名哲学 ■ASTERIA WARPについて ■19年連続国内シェアNo.1 ■10,000社以上の企業での導入実績 ■ノーコードだから誰でも使える ■市场地位:日本市场的绝对王者 ■核心产品力&am…...

BrowserGym:基于LLM的浏览器自动化智能体开发实战指南

1. 项目概述:当浏览器自动化遇上大语言模型最近在探索大语言模型(LLM)与真实世界应用交互的边界时,我深度体验了ServiceNow开源的BrowserGym项目。这不仅仅是一个简单的网页自动化工具,它更像是一个为LLM量身定制的“浏…...

【收藏级】2026年大模型入门指南:小白程序员必看,告别AI焦虑,轻松切入AI行业

这篇文章想聊清楚一个很现实的问题:在2026年AI热潮愈演愈烈的今天,小白和程序员到底该怎么低成本进入AI行业? 如果你最近也在焦虑、在内耗,刷到各种AI热点就心慌,不知道该学什么、不知道该怎么开始,甚至担心…...

构建本地优先的代码片段管理工具:从设计到实践

1. 项目概述:一个为开发者量身定制的代码片段管理工具如果你和我一样,是个每天和代码打交道的开发者,那你肯定遇到过这样的场景:为了解决一个特定的问题,你花了半天时间在网上搜索、调试,终于写出了一段堪称…...

Flutter for OpenHarmony 中 webview_flutter 适配实战指南

Flutter for OpenHarmony 中 webview_flutter 适配实战指南 欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net 摘要 本文基于真实项目实践,完整介绍了在 Flutter for OpenHarmony(以下简称 FOH)工程中&…...

LangGraph 终极解析:从 “玩具 Agent“ 到 “生产级智能体“ 的核心武器

目录 LangGraph 终极解析:从 "玩具 Agent" 到 "生产级智能体" 的核心武器 一句话定位 为什么必须学 LangGraph?(LangChain 的致命缺陷) LangGraph 四大核心概念(一张图搞懂) 1. S…...

python系列【仅供参考】:js2py模块--python中执行js

js2py模块--python中执行js js2py 1. 在python中执行js代码 2. js代码翻译 3. 在js中调用Python函数 4. 在js中调用Python模块 js2py Python中执行JS代码,通常用两个库:js2py,pyexecjs。当网页使用 js 加密时我们可以使用这些库来分析 js 的实现逻辑,获取加密信息。 js2p…...

下载安装 Temurin® JDK JDK 21 - LTS 速度很慢,有办法加速吗?

下载 Temurin JDK JDK 21 - LTS 速度很慢,有办法加速吗? 加速下载 Temurin JDK 21 的方法 方法一:清华大学 TUNA 镜像(推荐 ⭐⭐⭐⭐⭐) 这是目前最快、最稳定的国内镜像,速度可以跑满带宽。 直接访问目…...

Godot XR Tools:加速VR/AR开发的模块化工具集与实战指南

1. 项目概述:Godot XR Tools 是什么? 如果你正在用 Godot 引擎捣鼓 VR 或 AR 项目,大概率会遇到一些“通用但繁琐”的问题:怎么让虚拟手自然地抓取物体?怎么实现一个稳定可靠的传送移动机制?UI 界面在 3D …...

python系列【仅供参考】:JS的解析与Js2Py使用

JS的解析与Js2Py使用 JS的解析与Js2Py使用 简介: JS的解析 事件监听器 搜索关键字 请求关联JS文件 Js2Py Js2Py的简单使用 安装Js2Py 执行JavaScript代码 调用JavaScript函数 Js2Py的应用示例 创建JavaScript文件 使用JavaScript JS的解析与Js2Py使用 简介: Js2Py是一个Pyt…...

基于工作流的低代码AI应用开发:Flock平台核心架构与实战指南

1. 项目概述:Flock,一个为AI应用构建者准备的“乐高积木”如果你正在寻找一个工具,能够让你像搭积木一样,快速构建出功能强大的聊天机器人、智能客服,甚至是能自主协作的多智能体系统,那么Flock很可能就是你…...

深入Android Framework:构建稳定、高效的无人售卖机系统

摘要: 本文聚焦于Android Framework框架层,探讨其在无人售卖机系统开发中的核心价值与应用实践。区别于常规应用层开发,无人售卖机因其特殊的运行环境(如弱网、断电风险、多外设交互)及业务需求(如交易安全、设备状态监控、离线能力),对Android系统的底层能力提出了更高…...

如何在华为HarmonyOS设备上部署microG服务:解决签名验证的完整技术指南

如何在华为HarmonyOS设备上部署microG服务:解决签名验证的完整技术指南 【免费下载链接】GmsCore Free implementation of Play Services 项目地址: https://gitcode.com/GitHub_Trending/gm/GmsCore microG Services是一个开源免费的Google Play服务替代框架…...