1. 在MyBatis中$和#有什么区别

在MyBatis中

  • #{}会预编译生成PrepareStatement防止SQL注入,参数会被转义;
  • ${}直接拼接SQL字符串,存在注入风险。
  • 前者适用于参数值替换,后者用于动态表名/列名等需原生SQL的场景。优先使用#{}确保安全性。

2. 介绍一下MyBatis的缓存机制

MyBatis的缓存机制:

  • 一级缓存也称为本地缓存,它默认启用且不能关闭。一级缓存存在于SqlSession的生命周期中,即它是SqlSession级别的缓存,在同一个SqlSession中查询时,MyBatis会把执行的方法和参数通过算法生成缓存的键值,将键值和查询结果存入一个Map对象中,如果同一个SqlSession中执行的方法和参数完全一致,则会将缓存的对象返回;
  • 二级缓存则为SqlSessionFactory,mybaits的全局配置setting有一个参数cacheEnabled,这个参数是二级缓存的全局开关,默认值是true,初始状态为启用状态,映射语句文件中的所有SELECT 语句将会被缓存。
    • 映射语句文件中的存在INSERT 、UPDATE 、DELETE 语句时会刷新缓存。
    • 缓存会使用Least Recently U sed ( LRU ,最近最少使用的)算法来收回

3. MyBatis里如何实现一对多关联查询?

在MyBatis中实现一对多关联查询可通过两种方式:

  • 1)在XML映射文件中使用<collection>标签,通过嵌套结果集(联表查询)或嵌套查询(分次查询)关联子表数据;
  • 2)使用注解方式通过@Results@Result注解,结合@Many指定子查询方法。需在实体类中定义包含多个子对象的集合属性,并通过column参数传递关联字段。

4. Mybatis如何防止sql注入。

MyBatis默认用#{}做参数绑定,底层是PrepareStatement,参数会被自动转义,不会直接拼接入SQL,这样就能防止SQL注入了。只要不用${},安全性就比较高。

5. 说一下 MyBatis 和 MyBatis Plus 的区别。

MyBatis是基础ORM框架,需手动编写SQL与配置;
MyBatis Plus是其增强工具,提供通用Mapper、自动生成SQL、内置分页等功能,简化CRUD操作开发。
后者基于前者扩展,减少代码量但保留MyBatis灵活性。

6. MyBatis如何实现分页查询?

MyBatis实现分页主要有三种方式:

  1. 使用RowBounds对象进行内存分页(适用于小数据量);
  2. 在SQL中直接编写LIMIT/OFFSET语句(如MySQL);
  3. 通过分页插件(如PageHelper)自动拦截SQL并添加分页逻辑。物理分页推荐使用插件或数据库方言实现,避免内存溢出风险。

7. 讲一下Mybatis中动态sql的作用。

  1. Mybatis动态SQL用于根据不同条件灵活拼接SQL语句,避免手动拼接的繁琐和错误。
  2. 通过标签(如<if><choose><foreach>)实现逻辑判断、循环遍历等操作,简化复杂查询的编写。
  3. 适用于多条件查询、批量操作等场景,提升代码可读性和维护性,同时减少重复代码。

8. 讲一下Mybatis的插件原理。

  1. Mybatis插件基于拦截器机制,通过动态代理实现。
  2. 用户实现Interceptor接口并指定拦截的方法,Mybatis在启动时通过责任链模式为Executor、StatementHandler等核心组件生成代理对象。
  3. 执行目标方法时,插件按配置顺序逐层代理,最终调用原始方法。
  4. 该机制可用于SQL改写、日志增强等功能扩展。

9. 讲一下Mybatis的底层原理。

  1. 通过 SqlSessionBuilder 解析 XML 配置文件,构建 SqlSessionFactory。
  2. SqlSessionFactory 创建线程不安全的 SqlSession 实例。
  3. SqlSession 内部通过 Executor 管理 JDBC 连接。
  4. 执行 SQL 时:
    • 使用 Mapper 接口,通过动态代理生成 MapperProxy。
    • MapperProxy 委托 SqlSession 执行方法。
    • SqlSession 调用 Executor,后者创建 StatementHandler 处理 SQL。
    • StatementHandler 通过 ParameterHandler 设置参数,执行 SQL,并通过 ResultSetHandler 映射结果集。