文章目录
1.mybatis中#{}和${}的区别是什么?
答:#将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号;$将传入的数据直接显示生成在sql中。使用#能够很大程度防止sql注入,一般能用#的就别用$。MyBatis排序时使用order by 动态参数时需要注意,用$而不是#。
2.mybatis 有几种分页方式?
- 内存分页,查全量然后用subList
- SQL分页,limit
- 拦截器分页,定义拦截器,拦截以某些规则命名的方法,进行分页
- RowBounds分页。mybatis接口加入RowBounds参数,小数量可用,大数据量则不推荐。
3.RowBounds 是一次性查询全部结果吗?为什么?
答:对,RowBounds并不是直接在sql中实现,会将所有的结果都查询到,然后根据RowBounds中提供的offset和limit值来获取最后的结果,小数量可用,大数据量则不推荐。
4. mybatis 逻辑分页和物理分页的区别是什么?
答:逻辑分页内存开销比较大,在数据量比较小的情况下效率比物理分页高;在数据量很大的情况下,内存开销过大,容易内存溢出,不建议使用。物理分页 内存开销比较小,在数据量比较小的情况下效率比逻辑分页还是低,在数据量很大的情况下,建议使用物理分页。
5. mybatis 是否支持延迟加载?延迟加载的原理是什么?
答:支持。Mybatis延迟加载主要是通过动态代理的形式实现,通过代理拦截到指定方法,执行数据加载。MyBatis延迟加载主要使用:Javassist,Cglib实现。(原文:https://my.oschina.net/wenjinglian/blog/1857581?from=singlemessage)
6. 说一下 mybatis 的一级缓存和二级缓存?
一级缓存是SqlSession级别的缓存,他的作用域是同一个SqlSession,在同一个sqlSession中执行相同的Sql语句,第一次执行完毕的会将结果集写到缓存中,第二次就会从缓存中获取数据;
二级缓存是mapper级别的缓存,作用域是mapper的同一个namespace,不同的sqlsession在同一个namespace下执行相同的sql语句,第一次查询的结果缓存到缓存中,第二次则可从缓存中获取数据。
Mybatis默认开启一级缓存,没有开启二级缓存,二级缓存需要在xml配置中手动配置开启。
7. mybatis 和 hibernate 的区别有哪些?
(1)Mybatis和hibernate不同,它不完全是一个ORM框架,因为MyBatis需要程序员自己编写Sql语句,不过mybatis可以通过XML或注解方式灵活配置要运行的sql语句,并将java对象和sql语句映射生成最终执行的sql,最后将sql执行的结果再映射生成java对象。
(2)Mybatis学习门槛低,简单易学,程序员直接编写原生态sql,可严格控制sql执行性能,灵活度高,非常适合对关系数据模型要求不高的软件开发,例如互联网软件、企业运营类软件等,因为这类软件需求变化频繁,一但需求变化要求成果输出迅速。但是灵活的前提是mybatis无法做到数据库无关性,如果需要实现支持多种数据库的软件则需要自定义多套sql映射文件,工作量大。
(3)Hibernate对象/关系映射能力强,数据库无关性好,对于关系模型要求高的软件(例如需求固定的定制化软件)如果用hibernate开发可以节省很多代码,提高效率。但是Hibernate的缺点是学习门槛高,要精通门槛更高,而且怎么设计O/R映射,在性能和对象模型之间如何权衡,以及怎样用好Hibernate需要具有很强的经验和能力才行。
8. mybatis 有哪些执行器(Executor)?
SimpleExecutor:每执行一次update或select,就开启一个Statement对象,用完立刻关闭Statement对象。
ReuseExecutor:执行update或select,以sql作为key查找Statement对象,存在就使用,不存在就创建,用完后,不关闭Statement对象,而是放置于Map内,供下一次使用。简言之,就是重复使用Statement对象。
BatchExecutor:执行update(没有select,JDBC批处理不支持select),将所有sql都添加到批处理中(addBatch()),等待统一执行(executeBatch()),它缓存了多个Statement对象,每个Statement对象都是addBatch()完毕后,等待逐一执行executeBatch()批处理。与JDBC批处理相同。
9. mybatis 分页插件的实现原理是什么?
答:PageHelper拦截的是org.apache.ibatis.executor.Executor的query方法,其传参的核心原理是通过ThreadLocal进行的。当我们需要对某个查询进行分页查询时,我们可以在调用Mapper进行查询前调用一次PageHelper.startPage(…),这样PageHelper会把分页信息存入一个ThreadLocal变量中。在拦截到Executor的query方法执行时会从对应的ThreadLocal中获取分页信息,获取到了,则进行分页处理,处理完了后又会把ThreadLocal中的分页信息清理掉,以便不影响下一次的查询操作。
10. mybatis 如何编写一个自定义插件?
编写Interceptor的实现类,使用@Intercepts注解完成插件签名,说明插件的拦截四大对象之一的哪一个对象的哪一个方法,然后将写好的插件注册到全局配置文件中。(详细使用方式参考:https://www.cnblogs.com/gougouyangzi/articles/9993353.html)
转自:
https://mp.weixin.qq.com/s/KnSUprd6Z7zbpZAVR1OEdw
https://blog.csdn.net/u012661010/article/details/72801405