Mybatis面试题

Posted 小谢backup

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mybatis面试题相关的知识,希望对你有一定的参考价值。

1.简述Mybatis的Xml映射文件和Mybatis内部数据结构之间的映射关系?

答:Mybatis将所有Xml配置信息都封装到All-In-One重量级对象Configuration内部。在Xml映射文件中,标签会被解析为ParameterMap对象,其每个子元素会被解析为ParameterMapping对象。标签会被解析为ResultMap对象,其每个子元素会被解析为ResultMapping对象。每一个<select>、<insert>、<update>、<delete>标签均会被解析为MappedStatement对象,标签内的sql会被解析为BoundSql对象。

2.#{}和${}的区别是什么?

答:前者是xml文件中的变量占位符,它可以用于标签属性值和sql内部,属于静态文本替换,比如${driver}会被静态替换为com.mysql.jdbc.Driver。#{}是sql的参数占位符,Mybatis会将sql中的#{}替换为?号,在sql执行前会按序给sql的?号占位符设置参数值。#{item.name}的取值方式为使用反射从参数对象中获取item对象的name属性值,相当于param.getItem().getName()。

3.Xml映射文件中,除了常见的select|insert|updae|delete标签之外,还有哪些标签?

答:还有很多其他的标签,<resultMap>、<parameterMap&gt++;、<sql>、<include>、<selectKey>,加上动态sql的9个标签: trim | where | set | foreach | if | choose | when | otherwise | bind。其中为sql片段标签,通过标签引入sql片段,为不支持自增的主键生成策略标签(当使用oracle等不支持主键自增数据库时)。

4.简单的说一下MyBatis的一级缓存和二级缓存?

答:首先,要知道缓存是针对select来说的,没有查询就不存在缓存问题。 言归正传,对于一级缓存(又称SqlSession缓存),Mybatis首先去缓存中查询结果集,如果有则从缓存取出返回结果集而不走数据库。Mybatis内部存储缓存使用一个HashMap,keyhashCode+sqlId+Sql语句。value为从查询出来映射生成的pojo对象。 Mybatis的二级缓存(又称SqlSessionFactory缓存或进程缓存),它的作用域是一个sql mapper的namespace(pojo对应dao的路径),即在同一个namespace中查询sql可以从缓存中获取数据。二级缓存是可以跨SqlSession的。并且缓存介质除内存外还可以是外部存储设备如磁盘等。

5. 通常一个Xml映射文件,都会写一个Dao接口与之对应,请问,这个Dao接口的工作原理是什么?对于Dao接口里的方法,当参数不同时,方法能重载吗?

答:Dao接口,就是人们常说的Mapper接口。接口的全限名,就是映射文件中的namespace的值;接口的方法名,就是映射文件中MappedStatement的id值;接口方法内的参数,就是MapperStatement的parameterType值。(每一个<select>、<insert>、<update>、<delete>标签,都会被解析为一个MappedStatement对象。)当调用接口方法时,接口全限名+方法名拼接字符串作为key值,可唯一定位一个MappedStatement。

Dao接口的工作原理是JDK动态代理,Mybatis运行时会使用JDK动态代理为Dao接口生成代理proxy对象,代理对象proxy会拦截接口方法,转而执行MappedStatement所代表的sql,然后将sql执行结果返回。 Dao接口里的方法不管参数相不相同,都是不能重载的,因为其采取了全限名+方法名的保存和寻找策略。

6.Mybatis是否支持延迟加载?如果支持,它的实现原理是什么?

答:可以。只不过Mybatis仅支持association关联对象和collection关联集合对象的延迟加载,association指的就是一对一,collection指的就是一对多查询。在Mybatis配置文件中,可以配置是否启用延迟加载lazyLoadingEnabled=true|false。 它的原理是:使用CGLIB创建目标对象的代理对象,当调用目标方法时,进入拦截器方法,比如调用a.getB().getName(),拦截器invoke()方法发现a.getB()是null值,那么就会单独发送事先保存好的查询关联B对象的sql,把B查询上来,然后调用a.setB(b),于是a的对象b属性就有值了,接着完成a.getB().getName()方法的调用。这就是延迟加载的基本原理。 当然了,不光是Mybatis,几乎所有的包括Hibernate,支持延迟加载的原理都是一样的。

7.Mybatis都有哪些Executor执行器?它们之间的区别是什么?

答:Mybatis有三种基本的Executor执行器,SimpleExecutor、ReuseExecutor、BatchExecutor。

SimpleExecutor:每执行一次update或select,就开启一个Statement对象,用完立刻关闭Statement对象。

ReuseExecutor:执行update或select,以sql作为key查找Statement对象,存在就使用,不存在就创建,用完后,不关闭Statement对象,而是放置于Map<String, Statement>内,供下一次使用。简言之,就是重复使用Statement对象。

BatchExecutor:执行update(没有select,JDBC批处理不支持select),将所有sql都添加到批处理中(addBatch()),等待统一执行(executeBatch()),它缓存了多个Statement对象,每个Statement对象都是addBatch()完毕后,等待逐一执行executeBatch()批处理。与JDBC批处理相同。 作用范围:Executor的这些特点,都严格限制在SqlSession生命周期范围内。

8.Mybatis和Hibernate的不同有什么?

答:(1)设计理念。Mybatis不是纯粹的ORM框架(Hibernate则是纯粹的),需要根据实际情况书写特定的sql语句并通过XML或者注解配置,即无法做到数据库种类无关,相比Hibernate麻烦了一点,这个是缺点但也是优点:Mybatis更灵活,适用于对数据操作需求变化频繁的场景。可以这么看,在ORM中,Mybatis更专注于数据库(R),Hibernate更专注于对象(O)。也可以把Mybatis和Hibernate分别看作C和Java,一个面向过程(Mybatis是sql过程),一个纯粹面向对象。

(2)开发过程。Mybaits代码量一般较多,比较容易学,复杂查询时会相对“对手”更快(hibernate是在JDBC上进行了一次封装,而mybatis基于原生的jdbc,因此mybatis天生就有在平均运行速度上的优势)。Hibernate则站在对立面。 (3)扩展性。Mybatis开放了插件接口:不好分页?网上大神写的分页插件多得很;需要手写sql?按注解生成自动生成sql的插件早就有了;还有缓存的插件等等。可以说,只要肯在mybatis上花时间,你会发现orm这一块的所有问题它都有解决方案。这方面不是说Hibernate不好,因为Hibernate是个大家伙,所有的东西基本已经完整了,所以就没那么多也不需要那么多插件。

(4)移植性。MyBatis的数据移植方面,没有Hibernate好。Hibernate自动生成(使用HQL)的sql能适应更多的数据库,并且能反向生成表,关联映射功能也更好。

(5)SQL优化。Hibernate HQL语句的调优需要将SQL打印出来,而Hibernate的SQL被很多人嫌弃因为太丑了。MyBatis的SQL是自己手动写的所以调整方便。但Hibernate具有自己的日志统计。Mybatis本身不带日志统计,使用Log4j进行日志记录。

(6)缓存。Hibernate有更好的二级缓存机制,可以使用第三方缓存。MyBatis本身提供的缓存机制不佳。因为Hibernate对数据对象的操作实现了较为严密的封装,可以保证其作用范围内的缓存同步,而Mybatis提供的是半封闭的封装实现,因此对缓存的操作难以做到完全的自动化同步。

(7)对遗留系统的支持。很多系统在设计之初还没有orm思想,现在想“抢救”一下,用Mybatis就比Hibernate更合适。因为mybatis可以很容易做到不规范的映射对象和规范的映射对象共存,如果这种系统中再需要增加个复杂sql的功能,Mybatis只需要把sql手写出来,先把功能运行起来后再看看能不能变成自动生成的sql,而对Hibernate来说就很困难了。

(8)自动化。Hibernate属于全自动ORM映射工具,使用Hibernate查询关联对象或者关联集合对象时,可以根据对象关系模型直接获取,所以它是全自动的。而Mybatis在查询关联对象或关联集合对象时,需要手动编写sql来完成,所以,称之为半自动ORM映射工具。 虽然有很多的不同,但是Mybatis和Hibernate没有优劣之分,只有在特定业务场景下谁更适合之分。上面说过,就像Java和C都无法把对方给比下去一样,Hibernate代表了未来的方向,即真正的ORM;而Mybatis所依靠的速度与灵活性也会在它所适用的领域内大发光彩。所以未来二者都会有人去拥护、使用和改进。

9.如何预防sql注入?

答:使用占位符的方式写sql语句;

就先到这吧,谢谢浏览!


主要参考网址:

http://www.cnblogs.com/huajiezh/p/6415388.html http://www.cnblogs.com/wang-meng/p/5701990.html https://www.zhihu.com/question/21104468 https://stackoverflow.com/questions/1984548/hibernate-vs-ibatis


以上是关于Mybatis面试题的主要内容,如果未能解决你的问题,请参考以下文章

MyBatis概念性面试题整理汇总

SSM(Spring + Springmvc + Mybatis)框架面试题

MyBatis面试题(史上最全+不断升级)

10道不得不会的MyBatis面试题

Mybatis面试题

2023MyBatis全新面试题30题