MyBatis面试题
MyBatis
本文是对mybatis 3.x源码深度解析与最佳实践学习的总结,包括XML文件解析流程、SqlSession构建流程、CRUD执行流程、MyBatis扩展点,以及针对面试题进行源码分析。
mybatis 3.x源码深度解析与最佳实践下载:https://download.youkuaiyun.com/download/u013425841/12816685
MyBatis面试题
MyBatis一级缓存和二级缓存?
MyBatis默认开启一级缓冲,一级缓存是SQLSession级别,同一个SQLSessioon共享缓存,可以看到一级缓存实现是在BaseExecutor中
localCache是PerpetualCache的对象,PerpetualCache底层使用是HashMap实现的缓存
一级缓存合适失效?
1.设置flushCache=true
2. 在configuration标签的settings配置属性localCacheScope=STATEMENT,默认是Session级别
3.commit\rollback\update等操作,都会更新一级缓存,query对应的就是上面两种情况
MyBatis二级缓存,不同Session级别共享,STATEMENT级别的,需要设置开启二级缓存
二级缓存的执行流程:
1.首先获取缓存的Cache对象
2.判断是否存在对应key的缓存
3.不存在的话put进去对应的缓存
可以发现操作的是tcm对象,那么tcm对象是什么呢?
可以看到tcm是TransactionalCacheManager类的实例对象,它提供了事物和缓存操作的几种方法;
值得注意的是,二级缓存需要commit之后才能生效,没有commit的之前保存在中间map中
MyBatis 有几种执行器和区别?
SimpleExecutor:简单执行器
ReuseExecutor:可重用执行器
BatchExecutor:批量处理器
CachingExecutor:缓存执行器
https://javalearn.blog.youkuaiyun.com/article/details/112105106
Dao接口的工作原理是什么?Dao接口里的方法,参数不同时,方法能重载吗?
首先Dao接口的实现原理是基于JDK动态代理,详细处理流程如下:
1.首先在解析xml的时候会生成MapperProxyFactory存在Map中,key是当前Dao的Class类
- UserMapper mapper = session.getMapper(UserMapper.class);当执行getMapper方法会最终委托到该方法,在Map方法中获取到MapperProxyFactory方法,拿到代理工厂类。
- 继续执行newInstance方法可以看到,使用Proxy生成代理类
4.MapperProxy类实现了InvocationHandler类的invoke方法
5.继续执行CacheInvoker的invoke方法
6.委托给MapperMethod.execute方法,最终根据command命令执行对应的Insert、Update、DELETE、SELECT等方法
从mybatis的设计角度来说,dao是不允许重载的,因为mybatis在解析xml文件的时候,是用方法名作为唯一的key存储mappedStatement的
使用的是mybatis重写的StrictMap, put方法进行了验证,重复会抛出异常
Mybatis是如何进行分页的?分页插件的原理是什么?
Mybatis 使用 RowBounds 对象进行分页,它是针对 ResultSet 结果集执行的内存分页,而非物理分页。可以在 sql 内直接书写带有物理分页的参数来完成物理分页功能,也可以使用分页插件来完成物理分页。分页插件的基本原理是使用 Mybatis 提供的插件接口,实现自定义插件,在插件的拦截方法内拦截待执行的 sql,然后重写 sql,根据 dialect 方言,添加对应的物理分页语句和物理分页参数
Mybatis是否支持延迟加载?如果支持,它的实现原理是什么?
Mybatis 仅支持 association 关联对象和 collection 关联集合对象的延迟加载,association 指的就是一对一,collection 指的就是一对多查询。在 Mybatis配置文件中,可以配置是否启用延迟加载 lazyLoadingEnabled=true|false。它的原理是,使用 Javassist 创建目标对象的代理对象,当调用目标方法时,进入拦截器方法,比如调用 a.getB().getName(),拦截器 invoke()方法发现 a.getB()是null 值,那么就会单独发送事先保存好的查询关联 B 对象的 sql,把 B 查询上来,然后调用 a.setB(b),于是 a 的对象 b 属性就有值了,接着完成 a.getB().getName()方法的调用。这就是延迟加载的基本原理。当然了,不光是 Mybatis,几乎所有的包括 Hibernate,支持延迟加载的原理都是一样的。
创建代理对象
与我联系
Java/一对一零基础辅导/公司项目一对一辅导/日常Bug解决/代码讲解/毕业设计等 微信:study_51ctofx