文章目录
#{}和${}有什么区别?
#{}是预编译处理——能有效防止SQL注入保证程序运行安全。
${}是字符替换。
有几种分页方式?
- 逻辑分页:用mybatis自带的RowBounds进行分页,这是一次性查询所有数据,然后在数据中再进行检索。
- 物理分页:手写SQL分页或者使用PageHelper分页插件,这是查询指定条数的分页数据。
RowBounds是一次性查询全部结果吗?为什么?
不是。
mybatis是对jdbc进行封装处理的,在jdbc里有一个FetchSize的配置,它规定了每次最多从数据库中查询多少条数的数据,若是查询的数据很多,它会在执行next()时,再去查询其它数据。这样能有效的防止内存溢出。
ps:比方去取一万,ATM每次最多能取2500,就得分4次取,但过程是自动的,最终结果呈现出来就是一次性给你取出了一万。
Mybatis分页插件的实现原理是什么?
使用mybatis提供的插件接口实现自定义插件,在插件拦截方法里拦截待执行的SQL,并重写SQL,根据dialect方言来添加对应的物理分页语句和物理分页参数。
Mybatis的两种分页方式有什么区别?
- 逻辑分页:内存可能会溢出、对数据库压力也较大。
- 物理分页:弥补了逻辑分页的缺点。
延迟加载支持吗?实现原理是什么?
支持;设置lazyLoadingEnabled=true。
延迟加载指的是调用时触发加载而非初始化时加载信息。
/**
原理:
设A、B两对象,且没有触发事先存下的B对象的SQL,
这时调用a.getB().getName()会报null;
若触发事先存下的B对象的SQL,查询出B对象的数据,并调用a.setB(b),
这时调用a.getB().getName()便有数据了。
*/
说一下Mybatis的一级缓存和二级缓存
相同点:都是基于PerpetualCaChe的HashMap本地缓存。
不同点:一级缓存的作用域是Session级别;二级缓存的存储作用域是Mapper级别,且可自定义存储源。
- 一级缓存(默认开启):
声明周期与SQLSession保持一致,若在多个SQLSession或者分布式环境中操作数据库可能会出现脏数据。
当Session 刷新或关闭后,该Session中所有的缓存将被清空。 - 二级缓存:
流程:二级缓存 ——> 一级缓存 ——> 数据库。
若多个SQLSession间需要共享缓存,则要用到二级缓存。
开启:要用二级缓存属性类实现Serializable序列化接口(用来保存对象状态)。
缓存的更新机制:当某一个作用域进行了CUD操作后,默认该作用域下所有select中的缓存将被清除。
有哪些执行器?
- SimpleExecutor:每执行一次update / select,便开启一个Statement对象,用完即关。
- ReuseExecutor:执行update / select,将SQL作为key查找Statement对象,有则用无则创建,用完不关放置在Map中为下一次使用。
- BatchExecutor:执行update,将所有SQL都添加到批处理中,等待统一执行。它缓存了多个Statement对象,每个Statement对象都是在批处理完成后,等待逐一执行批处理。
BatchExecutor与jdbc批处理相同,所以没有select。