# 1. #{} 与 ${} 的 SQL 注入与预编译 A #{} 走预编译参数绑定,可防 SQL 注入 ✓ 正确答案 B #{} 直接拼接字符串,存在注入风险 C ${} 使用 PreparedStatement 占位符,安全 D #{} 与 ${} 功能完全相同
# 2. MyBatis 一级缓存(SqlSession 级别)与二级缓存(Mapper 级别)的失效场景 A 一级缓存是 Mapper 级别的,跨 SqlSession 共享 B 一级缓存作用域为 SqlSession,同一会话内增删改会清空该会话缓存 ✓ 正确答案 C 二级缓存是 SqlSession 级别的,默认开启 D 二级缓存跨 SqlSession 共享,且永远是数据一致的
# 3. MyBatis 二级缓存接入 Redis 等外部缓存时的一致性风险(脏读/过期策略) A 外部缓存多实例共享必然数据一致 B 设置 TTL 即可彻底解决一致性问题 C 二级缓存粒度是 namespace,无法感知跨表更新,可能产生脏读 ✓ 正确答案 D Redis 二级缓存与数据库永远同步
# 4. MyBatis 二级缓存的 flushInterval 与 Redis TTL 的协调及缓存穿透/雪崩防护 A 缓存穿透是大量 key 同时过期导致请求打库 B 缓存穿透指查询不存在的数据反复打库,可用空值缓存或布隆过滤器防护 ✓ 正确答案 C flushInterval 与 TTL 无需协调 D 缓存雪崩指热点 key 过期瞬间被多个请求同时回源
# 5. MyBatis 动态 SQL(<if>/<where>/<foreach>)的 SQL 拼接与预编译参数化 A 动态 SQL 拼接的值不使用参数化,存在注入风险 B <where> 标签会自动去除多余的前缀 AND/OR ✓ 正确答案 C <foreach> 只能用于 SELECT,不能用于 insert D <if> 无需 test 条件即可拼接
# 6. MyBatis 在 Spring Boot 3.5+ 对 SqlSessionFactory 与 SqlSessionTemplate 的整合细 A SqlSessionTemplate 是线程不安全的,每请求需新建 B SqlSessionTemplate 只能用于原生 JDBC C SqlSessionTemplate 与 Spring 事务无关 D SqlSessionTemplate 是线程安全的 SqlSession 代理,事务内复用同一个 SqlSession ✓ 正确答案
# 7. MyBatis 的 MappedStatement 缓存机制 A 每个方法执行时都会重新解析 MappedStatement B MappedStatement 在启动时解析并缓存,以 namespace+id 唯一标识 ✓ 正确答案 C MappedStatement 只缓存查询结果 D MappedStatement 与 SQL 无关
# 8. MyBatis 的 StatementHandler 与预编译 A StatementHandler 只负责结果集映射 B StatementHandler 与参数绑定无关 C StatementHandler 负责创建 Statement 并执行,是插件可拦截的核心对象 ✓ 正确答案 D StatementHandler 是 Executor 的下层执行辅助
# 9. MyBatis 的一级缓存与二级缓存(PerpetualCache) A PerpetualCache 是基于 HashMap 的简单缓存实现 ✓ 正确答案 B PerpetualCache 只能用于 Redis C PerpetualCache 是线程安全的分布式缓存 D PerpetualCache 不支持 get/put
# 10. 自定义插件实战,分页、字段加解密、慢查询统计应选择哪个拦截点(Executor/StatementHandler/ParameterHandler/ResultSetHandler)及执行顺序 A 分页查询应在 ParameterHandler 中改写 SQL B 字段加解密应在 ResultSetHandler 与 ParameterHandler 分别处理读写 ✓ 正确答案 C 慢查询统计应用在 ResultSetHandler 中 D 插件无法拦截 Executor
# 11. Mapper 接口与 XML 映射的协作 A SQL 语句的 id 可以与接口方法名不同 B XML 的 namespace 必须与接口全限定名一致 ✓ 正确答案 C Mapper 接口通过反射实现,不依赖动态代理 D 接口与 XML 不能共存
# 12. MyBatis 插件的 @Intercepts/@Signature 注解与多个插件的执行顺序(责任链模式) A @Signature 声明插件拦截的接口方法与参数类型 ✓ 正确答案 B 插件只能拦截 Executor,无法拦截其他对象 C @Intercepts 用于注册缓存 D 多个插件总是同时执行,无序
# 13. MyBatis 3.5.x 的 Optional 返回支持 A 有结果时返回 null B Optional 用于多结果集集合 C MyBatis 3.5 不支持 Optional D 查询无结果时返回 Optional.empty() ✓ 正确答案
# 14. MyBatis 与 Hibernate 的边界与选型 A Hibernate 是半自动 ORM B MyBatis 自动生成全部 SQL C MyBatis 是半自动 ORM,SQL 完全由开发者控制 ✓ 正确答案 D 两者选型完全等同于性能
# 15. MyBatis 与 Spring 6 的 JdbcClient 边界 A JdbcClient 提供流式链式 JDBC API,MyBatis 提供完整映射与动态 SQL ✓ 正确答案 B JdbcClient 与 MyBatis 完全相同 C JdbcClient 是完整 ORM 框架 D MyBatis 不支持动态 SQL
# 16. MyBatis 的 @Flush 与批量刷新 A @Flush 用于关闭缓存 B @Flush 只能用于 SELECT C @Flush 在 BATCH 模式下强制刷新批量语句到数据库 ✓ 正确答案 D @Flush 与 Executor 无关
# 17. MyBatis 的 @SelectProvider/@InsertProvider 动态 SQL A 它替代了所有 XML 配置 B 它只能用于固定 SQL C 它无法使用参数 D 它允许在 Java 方法中动态生成 SQL 字符串 ✓ 正确答案
# 18. MyBatis 的 Cursor 与流式查询 A Cursor 一次性加载全部结果到内存 B Cursor 与普通 List 查询完全一致 C Cursor 只能用于单行查询 D Cursor 惰性逐条读取,降低内存占用但占用连接 ✓ 正确答案
# 19. MyBatis 的 Executor 类型(SIMPLE/REUSE/BATCH) A SIMPLE 类型复用已创建的 Statement B REUSE 类型每次新建 Statement C BATCH 类型批量累积 SQL,在 flush 统一提交,适合批量写入 ✓ 正确答案 D 三种 Executor 性能完全相同
# 20. MyBatis 的 PageHelper 插件在分页查询中的物理分页与内存分页实现 A PageHelper 默认采用内存分页 B 物理分页会把全量数据加载到内存 C PageHelper 通过拦截 SQL 执行生成物理分页语句,按方言适配 ✓ 正确答案 D PageHelper 不需要数据库方言
# 21. MyBatis 的 ParameterHandler 与 ResultSetHandler A ResultSetHandler 负责将参数绑定到 PreparedStatement B ParameterHandler 负责将结果集映射为 Java 对象 C ParameterHandler 处理参数绑定,ResultSetHandler 处理结果映射 ✓ 正确答案 D 两者都只用于查询
# 22. MyBatis 的 ResultMap 在复杂对象关联映射(嵌套 ResultMap/Discriminator)中的设计 A Discriminator 用于根据某列值选择不同映射,实现多态 ✓ 正确答案 B 嵌套 collection 用于一对一映射 C 嵌套 select 不会产生 N+1 问题 D ResultMap 只能映射基本类型
# 23. MyBatis 的 RowBounds 与分页 A RowBounds 通过 offset/limit 实现内存分页,大数据量时性能差 ✓ 正确答案 B RowBounds 只能用于单表 C RowBounds 默认走数据库物理分页 D RowBounds 与物理分页完全相同
# 24. MyBatis 的 SQL 提取器(SqlSource) A StaticSqlSource 用于动态 SQL B SqlSource 生成的是 ResultSet C DynamicSqlSource 每次执行时根据参数动态解析生成 BoundSql ✓ 正确答案 D SqlSource 与 MappedStatement 无关
# 25. MyBatis 的 ScriptRunner 与脚本执行 A ScriptRunner 只能执行单条 SQL B ScriptRunner 用于执行 SQL 脚本文件,常用于数据库初始化 ✓ 正确答案 C ScriptRunner 经过 Mapper 映射 D ScriptRunner 是分页插件
# 26. MyBatis 的 TypeHandler 与自定义类型映射 A TypeHandler 只能用于查询 B 自定义 TypeHandler 无法全局注册 C TypeHandler 负责 Java 类型与 JDBC 类型之间的转换 ✓ 正确答案 D TypeHandler 是分页组件
# 27. MyBatis 的 XML 与注解的取舍 A 注解天然支持复杂动态 SQL B XML 只能用于简单查询 C XML 支持完整动态 SQL 与 ResultMap,适合复杂 SQL ✓ 正确答案 D 注解与 XML 不能混用
# 28. MyBatis 的 association/collection 的 N+1 解决 A 嵌套 ResultMap 必然产生 N+1 B N+1 只影响单表查询 C 嵌套 select 不会产生额外查询 D 嵌套 select 会产生 N+1 问题,嵌套 ResultMap 用 join 查询可避免 ✓ 正确答案
# 29. MyBatis 的插件机制(Interceptor)与责任链 A 插件无需 @Intercepts 配置 B 插件只能拦截一个对象 C proceed() 用于终止插件执行 D 插件通过 Interceptor 接口实现,用动态代理包装目标对象形成责任链 ✓ 正确答案
# 30. MyBatis 的 discriminator 与多态映射 A discriminator 根据结果集中某列的值选择不同的映射 ✓ 正确答案 B discriminator 用于分页 C discriminator 只能用于单表 D discriminator 与 ResultMap 无关
# 31. MyBatis 的 resultMap 与嵌套映射 A resultMap 只能映射基本类型 B resultMap 无法自动映射 C resultMap 支持 association/collection 等嵌套映射复杂对象 ✓ 正确答案 D resultMap 只能用于单表
# 32. MyBatis 的多结果集(Multiple ResultSets) A 多结果集只能用于普通查询 B MyBatis 支持一次查询返回多个结果集,结果集按顺序对应多个 resultMap ✓ 正确答案 C 多结果集只支持一个 resultMap D 多结果集无法映射
# 33. MyBatis 的延迟加载与 Javassist/CGLIB A 延迟加载只能用于基本类型 B 延迟加载总是立即加载全部数据 C 延迟加载不依赖 Session D 延迟加载通过代理在访问关联时再加载数据 ✓ 正确答案
# 34. MyBatis 的架构(SqlSessionFactory/SqlSession/Executor) A SqlSession 是线程安全的,可全局共享 B Executor 只负责分页 C SqlSessionFactory 由 SqlSessionFactoryBuilder 创建,是重量级单例 ✓ 正确答案 D SqlSession 直接执行 JDBC,不经过 Executor