问题精选-MyBatis
一、简述 Mybatis 的插件运行原理,以及如何编写一个插件?
1、Mybatis 仅可以编写针对 ParameterHandler、ResultSetHandler、StatementHandler、Executor
这 4 种接口的插件,Mybatis 通过动态代理,为需要拦截的接口生成代理对象以实现接口方
法拦截功能,每当执行这 4 种接口对象的方法时,就会进入拦截方法,具体就是
InvocationHandler 的 invoke()方法,当然,只会拦截那些你指定需要拦截的方法。
2、实现 Mybatis 的 Interceptor 接口并复写 intercept()方法,然后在给插件编写注解,指定要
拦截哪一个接口的哪些方法即可,记住,别忘了在配置文件中配置你编写的插件。
二、Mybatis 动态 sql 是做什么的?都有哪些动态 sql?能简述一下动态 sql 的执行原理不?
1、Mybatis 动态 sql 可以让我们在 Xml 映射文件内,以标签的形式编写动态 sql,完成逻辑
判断和动态拼接 sql 的功能。
2、Mybatis提供了9种动态sql标签:trim|where|set|foreach|if|choose|when|otherwise|bind。
3、其执行原理为,使用 OGNL 从 sql 参数对象中计算表达式的值,根据表达式的值动态拼接
sql,以此来完成动态 sql 的功能。
三、#{}和${}的区别是什么?
1、#{}是预编译处理,${}是字符串替换。
2、Mybatis 在处理#{}时,会将 sql 中的#{}替换为?号,调用 PreparedStatement 的 set 方法来
赋值。
3、Mybatis 在处理{}替换成变量的值。
4、使用#{}可以有效的防止 SQL 注入,提高系统安全性。
四、为什么说 Mybatis 是半自动 ORM 映射工具?它与全自动的区别在哪里?
Hibernate 属于全自动 ORM 映射工具,使用 Hibernate 查询关联对象或者关联集合对象
时,可以根据对象关系模型直接获取,所以它是全自动的。而 Mybatis 在查询关联对象或关
联集合对象时,需要手动编写 sql 来完成,所以,称之为半自动 ORM 映射工具。
五、Mybatis 是否支持延迟加载?如果支持,它的实现原理是什么?
1、Mybatis 仅支持 association 关联对象和 collection 关联集合对象的延迟加载,association
指的就是一对一,collection 指的就是一对多查询。在 Mybatis 配置文件中,可以配置是否启
用延迟加载 lazyLoadingEnabled=true|false。
2、它的原理是,使用 CGLIB 创建目标对象的代理对象,当调用目标方法时,进入拦截器方
法,比如调用 a.getB().getName(),拦截器 invoke()方法发现 a.getB()是 null 值,那么就会单独
发送事先保存好的查询关联 B 对象的 sql,把 B 查询上来,然后调用 a.setB(b),于是 a 的对
象 b 属性就有值了,接着完成 a.getB().getName()方法的调用。这就是延迟加载的基本原理。