JAVA面试-Mybatis

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

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值