文档:面试题:Mybatis
链接:有道云笔记
125.mybatis 中 #{}和 ${}的区别是什么?
#{}可以防止sql注入
${}传入对象最为合适
#{}预编译成 ?
${}直接显示数据
#{}将数据上加上“”;
126.mybatis 有几种分页方式?
分页插件PageHelper
使用sql Limit分页 (第一个参数页码,第二个参数显示条数)
拦截器分页
RowBounds分页
https://blog.csdn.net/chenbaige/article/details/70846902
127.RowBounds 是一次性查询全部结果吗?为什么?
并不是一次查询全部结果,可能一次查询很多数据。因为mybaitis封装jdbc ,jdbc规定,每次查询,有查询的个数限制。如果说是数据量比较大的时候,不建议使用rowBounds分页。数据量大的时候,很有可能会产生内存溢出。
标准回答:RowBounds 表面是在“所有”数据中检索数据,其实并非是一次性查询出所有数据,因为 MyBatis 是对 jdbc 的封装,在 jdbc 驱动中有一个 Fetch Size 的配置,它规定了每次最多从数据库查询多少条数据,假如你要查询更多数据,它会在你执行 next()的时候,去查询更多的数据。就好比你去自动取款机取 10000 元,但取款机每次最多能取 2500 元,所以你要取 4 次才能把钱取完。只是对于 jdbc 来说,当你调用 next()的时候会自动帮你完成查询工作。这样做的好处可以有效的防止内存溢出。
128.mybatis 逻辑分页和物理分页的区别是什么?
逻辑分页:一次性查询所有数据,然后从中检索数据,查询效率低,很有可能会出现内存溢出的现象、占用内存较大。RowBounds,这种就是逻辑分页
物理分页:指定查询的数据。sql中的Limit物理分页,查询效率高。
129.mybatis 是否支持延迟加载?延迟加载的原理是什么?
支持延迟加载,一对一,一对多可以实现延迟加载。
原理:使用CGLIB为目标对象建立代理对象,当调用目标对象的方法时进入拦截器方法。比如调用a.getb().getName(),拦截器方法invoke()发现a.getb()为null值,会单独发送事先保存好的查询关联b对象的sql语句,把b查询上来然后调用a.setB(b),于是a的对象的属性b就有值了,然后接着调用a.getb().getName(),这就是延迟加载的原理。
130.说一下 mybatis 的一级缓存和二级缓存?
一级缓存是默认开启的,其作用域是:sqlsession
二级缓存需要手动开启,要么在配置文件中配置,要么在<mapper>配一个标签<cache>,实体类实现序列化接口。
131.mybatis 和 hibernate 的区别有哪些?
sql手写:mybaits在xml中手写sql,hibernate中的sql语句基本上都是程序代码决定。
hibernate移植性大于mybatis
hibernate全自动,mybatis半自动
MySQL优化:mybatis比较好,因为sql语句都是自己手写的。
缓存方面:
都可以采用自带的二级缓存与第三方缓存。
132.mybatis 有哪些执行器(Executor)?
SimpleExecutor(简单执行器)每执行一次update与select,就开启一个Statement对象,用完立刻关闭Statement对象。
ReuseExecutor(重复执行器),每执行一次update与select,就开启一个Statement对象,用完不立刻关闭Statement对象。可以重复使用statement
BatchExecutor(批量执行器)缓存多个statement
https://www.jianshu.com/p/96ddaec4aea7
133.mybatis 分页插件的实现原理是什么?
134.mybatis 如何编写一个自定义插件?
暂时解决不了。