MyBatis面试常见问题

突然感觉MyBatis可问的东西不多,原理是非常简单,但是实现的细节非常多,并且许多语法特性也很难记,往往是写的时候去查

占位符的区别:${}#{}

感觉这个并不该属于MyBatis了,${}是Spring提供的SpEL表达式,用于将PropertySource注入到占位符当中,而#{}属于OGNL表达式,是MyBatis使用的参数占位符,在被编译成SQL语句的时候会被替换为问号,然后在执行过程中实现数值的注入

MyBatis的XML常见标签(除了增删改查的标签):

mapper:定义与哪个接口之间发生映射,执行逻辑,MyBatis配置文件最外层标签

resultMap:做结果映射

where包裹住if:做条件判断

DAO接口如何映射到XML上的,DAO中的方法可以重载吗

靠XML中的最外层mapper标签,指定namespace,实现了DAO接口与XML的映射,

至于其中方法的绑定,则是通过SELECT/DELETE标签的id属性指定方法名字,resultMap指定返回结果,parameterType指定参数实现绑定,在运行时候每个SETECT等会被转换成为一个MappedStatement

DAO中的方法是不能重载的,因为MyBatis的匹配模式仅限于权限定类名+方法名,与参数无关,尽管XML中有参数,可以作为判断的依据。

在运行时候走的是JDK动态代理

MyBatis进行分页

主要是通过分页插件进行完成的,分页插件会对SELECT语句进行增强,加上LIMIT语句。

MyBatis的插件运行原理

主要是针对SqlSession下四大对象:ParameterHandler(处理SQL语句参数)、StatementHandler(使用PreparementStatement执行操作,核心,很多扩展都是基于此的)、Executor(实现整体的调度)、ResultSetHandler(返回值的封装)进行拦截和处理,使用InvocationHandler来对这几个类进行增强

MyBatis的动态SQL

主要还是根据OGNL的几个判断表达式,如if来判断条件是否成立,来实现SQL是否连接,从而实现动态SQL。

MyBatis的映射关系

第一种情况:默认将类名映射成对象的属性名,实现对象的属性注入,MyBatis区分大小写,为了提高匹配的匹配度

第二种情况:使用resultMap标签,指定列名与属性的映射关系

MyBatis是支持延时加载的

支持延迟加载,就是只有当访问被加载对象时候才会执行SQL语句,主要是通过CGLIB增强get方法,只要返回值为null,就去执行对应的SQL语句

MyBatis中是通过mapper标签的namespace属性作为全限定类名,通过SELECT/DELETE,id作为方法名来进行匹配的

MyBatis内部存在的几种Executor(主要组件还有ParameterHandler、StatementHandler、Executor、ResultSetHandler):

SimpleExecutor(每次执行都创建一个Statement)、ReuseExecutor(相当于是一个Statement的池子,以SQL语句为key,实现Statement的重复利用)、BatchExecutor(批量执行SQL语句,一批SQL语句共用一个Statement)

如何使用:在DefaultSqlSessionFactory中调用带参数的ExecutorType方法创建SqlSession

MyBatis会将全部的配置(包含读取到的XML文件)都一起放入一个重量级对象Configuration中

MyBatis的执行过程(也就是不用starter时候我们使用MyBatis):

1、通过流的方式读取配置文件,通过配置文件让SqlSessionFactoryBuilder生成SqlSessionFactory

2、通过SqlSessionFactory获取SqlSession

3、通过SqlSession执行我们编写的SQL语句,核心是其中的Executor,Executor的执行链路为ParameterHandler、StatementHandler然后执行SQL语句,通过ResultSetHandler封装结果集

MyBatis涉及到的设计模式:

构造者模式:SqlSessionFactoryBuilder

工厂模式:SqlSessionFactory

代理模式:Mapper

模板方法模式:Executor

最后更新于