mybatis面试试题分析

1、mybatis的优点?

1、封装了大量的加载驱动,得到链接,释放连接等jdbc的操作,极大的简化了jdbc的开发
2、可以很好的与当前流行的框架spring结合
3、使用起来非常方便,会编写sql基本就会使用mybatis,入门门槛低
4、性能高,因为mybatis是手写sql,所以优化sql变得相当简单

2、mybatis的缺点?

1、对于某些多表联查可能需要开发者很强的数据库sql功底
2、迁移有点困难,因为mybatis很依赖数据库,不同的数据库sql还是有一定的差别的,所以后期要改变数据库很难

3、mybatis适用场景?

1、需要封装Dao层或者将xml与java代码分开时可以考虑使用mybatis
2、对整个系统性能要求比较高时可以想着使用mybatis,因为mybatis是手写sql,对数据库性能的控制权在自己手上

4、mybatis与hibernate的区别?

1、mybatis是一个半自动orm框架,hibernate是一个全自动的orm框架
2、mybatis灵活度比较高,因为是手写sql
3、mybatis入门低,不用再去学习像hibernate里的hql
4、hibernate对数据库的依赖不是很高,迁移数据库对hibernate的影响不是很大
5、hibernate不用写sql可以节省很多代码

5、#{}和${}的区别?

1、#{}是预编译处理,在处理的时候会当成?,需要prepareStatement对象set赋值
2、${}是字符串替换,在运行时会将${}替换成你传递的参数
3、#{}可以防止sql注入,而${}不会防止sql注入

6、数据库属性名与java字段名不一致时该怎么办?

1、在select查询的时候给数据库的列名取个别名,使别名与java字段名一致即可
2、在xml里的resultMap节点来映射,配置里面的property和column,使得数据库属性名与java字段名以一对应

7、Dao接口的工作原理,Dao接口的方法能够重载吗?

1、首先mybatis会将dao接口的接口名对应xml的名称,接口的全路径对应xml的namespace,接口的方法对应xml里的statement的id,像(select、delete、update、insert)都有一个id
2、不能重载,因为mybatis将接口的全路径+接口的方法名作为key存放在一个map集合里,而dao接口的工作原理是jkd的动态代理,当执行到dao接口的方法时,这时会生成一个叫做proxy的代理对象,代理对象会进入拦截器方法进而执行sql不会因为参数的不同而执行不同的sql

8、mybatis如何进行分页以及分页插件的原理?

1、mybatis默认的分页是使用一个叫做rowBounds的对象,这个对象是采用的ResultSet的结果集的内存分页,不是真正意义上的物理分页,他会将查询到的所有数据放到一个集合里,然后再根据需要的条数进行分页,很消耗性能
2、分页插件的原理是使用mybatis提供的插件接口,首先你需要自定义一个插件来实现interceptor,然后再重写intercept方法,在该方法里当执行到原sql的时候可以通过正则表达式判断是否需要分页,当需要分页的时候在原sql上拼接物理分页参数(limit,count),重写sql便可以做到实现真正意义上的物理分页

9、mybatis如何将sql执行的结果封装为目标对象返回的?都有哪些映射形式?

1、myabtis会将查询到的结果封装到ResultSet结果集里,然后根据你自己配置的映射关系来给属性赋值,匹配上的便能赋值,匹配不上的不能赋值
2、映射形式有两种
	a、select查询的时候起别名
	b、在xml的ResultMap节点的property和column进行以一匹配

10、mybatis如何执行批量插入

1、首先写一个简单的插入sql语句
2、然后创建一个list集合存储批量插入的属性值
3、使用executorType.batch创建一个sqlsession的对象
4、循环遍历list集合,执行体便是循环插入语句

11、如何自动获取生成的主键值?

1、在xml的select节点下配置usegeneratedkeys="true" keyproperty="id"即可,这样在插入的时候就会返回主键了

12、在mapper里如何传递多个参数?

1、xml里接收的参数可以是#{arg0},#{arg1},#{arg2}来对应你接口方法的第一、第二、第三个参数
2、可以在接口方法的参数前加@param("参数名")注解,这样就可以在xml里写#{参数名}了
3、可以将参数封装一个map集合里,直接传递集合

13、mybatis的动态sql有什么用?执行原理?有哪些动态sql?

1、动态sql是写在xml里的,以标签形式书写sql,可以以动态条件来拼接sql
2、执行原理是在执行时会根据表达式的值,完成逻辑判断并拼接完整的sql
3、9个,分别是trim|choose|if|otherwise|when|where|bind|foreach|set

14、xml里除了常见的select/insert/update/delete标签外,还有什么标签?

1、sql include resultMap parameterMap selectKey
2、9个动态标签 trim|choose|when|where|if|bind|otherwise|set|foreach

15、mybatis的xml文件里,不同的xml文件,id是否可以相同?

1、如果没有配置namespace,id不能相同;如果配置了namespace,并且在不同的namespace里id可以相同
2、mybatis会根据接口的全路径+接口的方法名对应xml里的namespace+id作为key存放到map里,如果没有配置namespace或namespace相同那么只剩下一个id了,在map里key相同会覆盖,这样导致执行sql时会错乱

16、为什么说mybatis是半自动orm框架,它与全自动的orm框架的区别在哪里?

1、因为mybatis需要你手写sql,而全自动orm框架只需要通过映射关系操作对象就能改变数据库的值,而mybatis不能做到像hibernate那样直接操作,但是mybatis又封装了大量的jdbc的操作,所以mybatis被称为半自动的orm框架

17、mybatis实现一对一的查询有几种形式?具体怎么操作?

1、两种形式
	a、联合查询,在resultMap节点的assocation节点配置一对一就可以了
	b、嵌套查询,先查询一个表,然后根据这个表的id在去另外的表查询,不同的是在select属性里配置assocation

18、mybatis实现一对多的查询有几种形式?具体怎么操作?

1、两种形式
	a、联合查询,在resultMap节点里配置collection节点配置一对多就可以了
	b、嵌套查询,先查询一个表,然后根据这个表的id去另外的表查询,不同的是在select属性里配置collection

19、mybatis是否支持延迟加载?如果支持,原理是什么?

1、支持,但是只支持assocation和collection关联对象的延迟加载,只需要在mybatis.xml里配置lazyLoadingEnabled=true|false即可
2、原理是利用Cglib创建一个代理对象,当调用目标方法时,会首先进入拦截器方法,例如: a.getB().getName(),首先会查询a.getB(),此时会查询到null值,这时代理对象会首先会查询b对象,然后先a.setB(b),这时候再查询a.getB().getName()就有值了

20、描述一下mybatis的一级缓存和二级缓存?

1、一级缓存作用域是单个sqlSession,二级缓存作用域是所有的sqlSession(namespace|mapper)
2、一级缓存和二级缓存本质上都是基于PerpetualCache的hashMap缓存
3、一级缓存默认是开启的,二级缓存默认是关闭的,若要打开二级缓存可以在mybatis.xml里配置<Cache />并在开启二级缓存的类上实现serializable序列化即可
3、当进行c/u/d操作时,一级缓存和二级缓存都会被clear

21、什么是mybatis的接口绑定?有哪些实现方式?

1、接口绑定就是在Dao层定义一些接口,然后接口没有实现类,只是绑定一个sql语句
2、2种实现方式
	a、在Dao层的方法上加上注解 例如(@Select(select * from User))
	b、在对应的xml里写sql

22、使用mybatis的mapper接口调用时有哪些要求?

1、mapper的接口名和xml名一致
2、mapper的全路径和xml的namespace一致
3、mapper的方法名和xml的statement的id一致
4、mapper的方法返回参数类型和statement的返回类型一致
5、mapper的方法参数类型和statement的参数类型一致

23、mapper编写有几种形式?分别是什么,以及加载顺序?

1、4种
	a、<package name=""></package> 会扫描整个mapper包    -->package
	b、<mapper resource="mapper.xml"></mapper>          -->resource
	c、<mapper url=""></mapper>                         -->url
	d、<mapper class=""></mapper>                       -->class
其中bcd只能同时出现一种,>1种时mybatis就不会解析
解析顺序:先解析resource,再解析url,最后解析class

24、mybatis插件的运行原理以及如何编写一个插件?

1、mybatis只能拦截ParameterHandler、ResultSetHandler、StatementHandler、Exector这四大对象,mybatis使用了jdk的动态代理,在执行这4个对象的接口方法时,首先会生成一个代理对象并进入拦截器方法,具体就是InvocationHandler的invoke()方法。
2、首先需要实现Inteceptor的intercept()方法,然后再给该插件编写一个注解,指定拦截器拦截哪些接口的哪些方法

25、ResultMap和ResultType的差别?

1、ResultMa是用来指定数据库中的列名与java的属性一一绑定
2、ResultType是用来设置java的返回值与数据库类型一一对应(例如:String对应varchar)

26、Mybatis映射文件中,如果A标签通过include引用了B标签的内容,请问,B标签能否定义在A标签的后面,还是说必须定义在A标签的前面?

1、可以在前面也可以在后面
2、因为mybatis在解析xml的时候会按顺序解析一遍,把不能解析的标签先标记一下放到一个map集合里,继续解析能解析的标签,解析一遍完成之后,会再次循环解析不能解析的标签

27、spring和mybatis整合之后为什么一级缓存会失效,如何开启?

1、一级缓存的作用域是sqlSession,而spring帮你管理了sqlSession对象,它不让你自己管理,所以它不知道你什么时候close或者刷新缓存,spring它就在dao方法调用完成后自动销毁了,这样就跳过了sqlSession,因此一级缓存会失效
2、只需要开启事务,一级缓存就自动开启了,因为一旦你开启事务,spring不会执行完dao方法执行完就销毁sqlSession而,是在事务关闭时才销毁

28、二级缓存要注意的点?

1、二级缓存不能存放那种是一直累加很大的数据
2、二级缓存是基于命名空间的,当有多个namespace共同操作一个表的时候,最好不要用二级缓存,因为这样可能会造成脏读

29、mybatis四大对象及作用?

1、ParameterHandler                   -->对预编译语句进行配置
2、ResultSetHandler                   -->封装结果集
3、StatementHandler                   -->处理数据库会话,执行sql
4、Exector                            -->一个执行器,操作java与数据库交互的对象

30、CacheKey的计算规则或者说如何判断两次查询是一样的?

CacheKey cacheKey = new CacheKey();
1、先判断sql的id是否相同(statement 的id)
2、如果开启分页就会判断分页的起始位置是否相同,查询到的条数是否相同
3、绑定的sql是否相同
4、传递的参数是否相同

猜你喜欢

转载自www.cnblogs.com/liulong99/p/mybatis.html