mybatis面试题
1.请介绍下MyBatis sql语句的解析过程原理
通过责任链的方式一个一个解析sql node
2.请介绍下MyBatis缓存的原理
装饰器+责任链的方式
3.请介绍下MyBatis插件的原理
动态代理+责任链的方式
4.MyBatis执行SQL查询的流程
mybatis执行流程
-
加载配置文件并初始化(SqlSession)
配置文件来源于两个地方,一个是配置文件(主配置文件conf.xml,mapper文件*.xml),一个是java代码中的注释,将sql的配置信息加载成为一个mappedstatement对象,存储在内存之中(包括传入参数的映射配置,结果映射配置,执行的sql语句)。 -
接收调用请求
调用mybatis提供的api,传入的参数为sql的id(有namespase和具体sql的id组成)和sql语句的参数对象,mybatis将调用请求交给请求处理层。 -
处理请求
根据sql的id找到对应的mappedstatament对象。
根据传入参数解析mappedstatement对象,得到最终要执行的sql。
获取数据库连接,执行sql,得到执行结果
Mappedstatement对象中的结果映射对执行结果进行转换处理,并得到最终的处理结果。释放连接资源 -
返回处理结果
5.Mybatis 是如何进行分页的?分页插件的原理是什么?
Mybatis 使用 RowBounds 对象进行分页,它是针对 ResultSet 结果集执行的内存分页,而非物理分页。可以在 sql 内直接书写带有物理分页的参数来完成 物理分页功能,也可以使用分页插件来完成物理分页。
分页插件的基本原理是使用 Mybatis 提供的插件接口,实现自定义插件,在插件的拦截方法内拦截待执行的 sql,然后重写 sql,根 据 dialect 方言,添
加对应的物理分页语句和物理分页参数。
6.为什么说 Mybatis 是半自动 ORM 映射工具?它与全自动的区别在哪里?
Hibernate 属于全自动 ORM 映射工具,使用 Hibernate 查询关联对象或者关 联集合对象时,可以根据对象关系模型直接获取,所以它是全自动的。而Mybatis 在查询关联对象或关联集合对象时,需要手动编写 sql 来完成,所以,称之为半自动 ORM 映射工具
7.Mybatis 的一级、二级缓存
1)一级缓存: 基于 PerpetualCache 的 HashMap 本地缓存,其存储作用域为Session,当 Session flush 或 close 之后,该 Session 中的所有 Cache 就 将清空,默认打开一级缓存。
2)二级缓存与一级缓存其机制相同,默认也是采用 PerpetualCache,HashMap 存储,不同在于其存储作用域为 Mapper(Namespace),并且可自定义存储源, 如 Ehcache。默认不打开二级缓存,要开启二级缓存,使用二级缓存属性类需要实现 Serializable 序列化接口(可用来保存对象的状态),可在它的映射文件中配置 ; 3)对于缓存数据更新机制,当某一个作用域(一级缓存 Session/二级缓存Namespaces)的进行了 C/U/D 操作后,默认该作用域下所有 select 中的缓存将被 clear
8.简述 Mybatis 的插件运行原理,以及如何编写一个插件
Mybatis作为一个优秀的ORM插件有很强大的灵活性,通过插件可以很方便地扩展Mybatis的功能。
Mybatis的插件相当于拦截器,是使用JAVA动态代理来实现的。Mybatis对持久层的操作借助于四大组件(Executor,StatementHandler,ParameterHandler,ResultSetHandler)。在创建这四类对象时会判断是否有配置好的插件,若是有则返回被插件代理的动态代理对象。在执行这四类对象的方法时,先判断执行的方法是否是需要代理的方法,如果是则执行插件类的增强方法。在四大对象创建的时候:
在Mybatis中每个创建出来的对象并不是直接返回的,而是获取所有的拦截器interceptor.plugin(target);
在获取到所有的Interceptor(插件需要实现的接口)后;调用interceptor.plugin(target);返回target包装后的对象;
插件机制,我们可以使用插件为目标对象创建一个代理对象;aop(面向切面)我们的插件可以认为是四大对象创建出代理对象,代理对象就可以拦截到四大对象的每一个执行。
Mybatis插件编写思路:
Mybatis 的插件就是拦截器,目的是增强核心对象的功能.它是基于动态代理实现的.
首先要编写一个类实现Interceptor接口并实现其中的方法。
然后通过@Intercepts注解标识这是个Mybatis插件,在注解内部通过@Signature来确定具体拦截的是哪个组件的哪个类、方法。
最后将该插件配置在 Mybatis 的 sqlMapConfig.xml 配置文件中,以便Mybatis识别该插件并加入到它的InterceptorChain中。
<plugins>
<plugin interceptor="com.lagou.plugin.MySqlPagingPlugin">
<property name="name" value="test"/>
</plugin>
</plugins>