Mybatis 面试题

Mybatis 面试题

Mybatis 动态 sql 是做什么的?都有哪些动态 sql?简述一下动态 sql 的执行原理?

Mybatis 动态 sql 是指在进行 sql 操作时,根据传入的参数对象、参数值去匹配条件进行动态判断、循环、拼接等情况。

动态 sql 大致有以下几种:

trim、where、set、foreach、if、choose、when、otherwise、bind

动态 sql 执行原理:

  1. 首先在解析 XML 配置文件的时候会创建 SqlSource对象,调用 LanguageDriver#createSqlSource方法

  2. createSqlSource 方法底层使用 XMLScriptBuilder#parseScriptNode 方法对 XML 文件进行解析

  3. parseScriptNode 方法内部会调用 parseDynamicTags 方法会把每个标签节点添加到对应的 handler 中并判断是否为动态 sql

  4. 然后根据返回的 DynamicSqlNode 添加到 DynamicSqlSource 中

  5. 根据 DynamicSqlSource#getBoundSql 方法获取到 BoundSql 对象

  6. 由 Executor 执行时,调用 DynamicSqlSource 解析获取 BoundSql 以及替换 sql 的参数值

Mybatis 是否支持延迟加载?如果支持,实现原理是什么?

Mybatis仅支持 association 关联对象和 collection 关联集合对象的延迟加载,association 指的就是一对一,collection 指的就是一对多查询。在 Mybatis 配置文件中,可以配置是否启用延迟加载 lazyLoadingEnabled = true|false。

原理:使用 CGLIB 创建目标对象的代理对象,当调用目标方法时,进入拦截器方法,比如调用 A.getB().getName(),拦截器 invoke() 方法发现 A.getB() 是 null 值,那么就会单独发送事先保存好的查询关联 B 对象的 sql,把 B 查询上来,然后调用 A.setB(b),于是 a 的对象 b 属性就有值了,接着完成A.getB().getName() 方法的调用。

Mybatis 有哪些 Executor 执行器?它们之间的区别是什么?

Mybatis 有三种基本的 Executor 执行器,SimpleExecutor、ReuseExecutor、BatchExecutor。

SimpleExecutor:每执行一次 update 或 select 操作,就开启一个 Statement 对象,用完立刻关闭 Statement 对象。

ReuseExecutor:执行 update 或 select 操作,以 sql 作为 key 查找 Statement 对象,存在就使用,不存在就创建,用完后,不关闭 Statement 对象,而是放置于 Map<String, Statement> 内,供下一次使用,达到重复使用Statement 对象的目的。

BatchExecutor:执行 update(没有select,JDBC批处理不支持 select 操作),将所有 sql 都添加到批处理中 addBatch() 方法,等待统一执行executeBatch() 方法,它缓存了多个 Statement 对象,每个 Statement 对象都是 addBatch() 完毕后,等待逐一执行 executeBatch() 批处理。与 JDBC 批处理相同。

作用范围:Executor 的这些特点,都严格限制在 SqlSession 生命周期范围内。

Mybatis中如何指定使用哪一种 Executor 执行器?

在 Mybatis 配置文件中可以指定默认的 Executor 执行器类型,或者给 DefaultSqlSessionFactory 创建 SqlSession 方法传递 ExecutorType 类型参数。

简述一下 Mybatis 的一级、二级缓存(分别从存储结构、范围、失效场景)

一级缓存是 SqlSession 级别的缓存,不同 sqlSession 之间的缓存结构为 HashMap,当对数据进行增、删、改或者调用 SqlSession 的 close 方法时会导致一级缓存失效。

二级缓存是 Mapper 级别的缓存,多个 SqlSession 去操作同一个 Mapper 的 sql 语句时,可以共享二级缓存,底层的缓存数据结构为 private Map<Object, Object> cache = new HashMap<>();开启二级缓存需要在 <select>标签上加上 useCache=“true”,在数据更新、删除时需要手动开启 flushCache 刷新缓存。

简述 Mybatis 的插件运行原理,以及如何编写一个插件?

Mybatis 仅可以编写针对 ParameterHandler、ResultSetHandler、StatementHandler、Executor 这 4 种接口的插件,Mybatis 使用 JDK 的动态代理,为需要拦截的接口生成代理对象以实现接口方法拦截功能,每当执行这 4 种接口对象的方法时,就会进入拦截方法,具体就是 InvocationHandler 的invoke() 方法,当然,只会拦截那些你指定需要拦截的方法。实现 Mybatis 的Interceptor 接口并复写 intercept() 方法,然后再给插件编写注解,指定要拦截哪一个接口的哪些方法即可,此外还需要在配置文件中配置你编写的插件。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值