面试题-MyBatis框架
前言
MyBatis框架部分的题目,是我根据Java Guide的面试突击版本V3.0再整理出来的,其中,我选择了一些比较重要的问题,并重新做出相应回答,并添加了一些比较重要的问题,希望对大家起到一定的帮助。
系列文章:
MyBatis
-
"#{}"和${}的区别是什么?
- ${}属于静态文本替换,可以写在标签的属性值和sql内部
- "#{}"是sql中的参数占位符,mybatis会把它替换成?执行sql的时候会使用PreparedStatement设置参数的方法按序给问号设置值。
-
最佳实践中,通常⼀个 Xml 映射⽂件,都会写⼀个 Dao 接⼝与之对应,请
问,这个 Dao 接⼝的⼯作原理是什么?Dao 接⼝⾥的⽅法,参数不同时,⽅法能重
载吗?- 工作原理:JDK动态代理,运行时实时创建代理对象,在代理方法中执行SQL查询然后返回数据。
- 是否可以重载:不可以。因为mybatis是根据类的全限定名+方法名找SQL的,所以不支持重载
-
Mybatis 是如何进⾏分⻚的?分⻚插件的原理是什么?
MyBatis中支持逻辑分页,也支持物理分页。
- 逻辑分页:可以使用RowBounds进行逻辑分页,它是基于结果集的内存分页
- 物理分页:可以在sql语句中实现;或者使用MyBatis的分页插件。分页插件的原理是根据方言重写SQL。
我们项目在实际使用中使用的是PageHelper进行分页,PageHelper的原理其实也是实现了mybatis的插件接口,在接口中实现自己的逻辑。
-
Mybatis插入单条数据时,如何返回主键?
- 如果要返回自增主键
- 可以使用insert属性的useGenerateKeys和keyProperty指定对象属性即可,这里用法的底层原理就是使用select LAST_INSERT_ID();
- 可以使用
标签即可,标签中使用after和select LAST_INSERT_ID();来返回自增主键
- 如果要返回非自增主键
- 可以使用
标签即可,标签中使用before和select uuid();来返回主键
- 可以使用
- 如果要返回自增主键
-
MyBatis批量插入时,如何返回自增主键?
和单条插入是类似的。
-
Mybatis 动态 sql 是做什么的?都有哪些动态 sql?能简述⼀下动态 sql 的执⾏原理不?
MyBatis提供了9种动态SQL标签,动态SQL的原理主要是通过OGNL表达式计算表达式的值,根据表达式的值来动态拼接SQL。
实际项目中,我们最常用的就是where和if标签,可以用在列表的不定条件查询的SQL中;如果有批量插入,也会使用foreach标签。trim标签也可以去除多余的and和多余的逗号。
-
Mybatis 是如何将 sql 执⾏结果封装为⽬标对象并返回的?都有哪些映射形式?
- resultType:除了map以外,其他的情况需要保证列名和对象属性的映射正确,做法有两种:1. 修改字段别名为对象的属性名:resultType="类名";2. 不修改别名,增加一个属性
mapUnderscoreToCamelCase
配合resultType="类名";使用也可以- 可以返回单个对象
- 可以返回单条数据的map,resultType="map"
- 可以返回对象集合,resultType="类名"
- 可以返回多条数据的map<Key,类名>,需要在接口中指定@MapKey("lastName")注解
- resultMap,逐一定义列名和属性名的映射关系
- resultType:除了map以外,其他的情况需要保证列名和对象属性的映射正确,做法有两种:1. 修改字段别名为对象的属性名:resultType="类名";2. 不修改别名,增加一个属性
-
Mybatis 能执⾏⼀对⼀、⼀对多的关联查询吗?都有哪些实现⽅式,以及它们之间的区别?
待完成...
-
Mybatis 是否⽀持延迟加载?如果⽀持,它的实现原理是什么?
支持,可以配置lazyLoadingEnabled=true|false来实现延迟加载。
Mybatis仅支持association和collection的延迟加载,延迟加载的原理是,当实际使用到需要延迟加载的属性时,发现为null,然后会去执行SQL把对象查询出来,然后设置属性值。
-
Mybatis 的 Xml 映射⽂件中,不同的 Xml 映射⽂件,id 是否可以重复?
不同的XML映射文件,如果配置了namespace,那么id可以重复,如果没有使用namespace,那么id不可以重复。原因是MyBatis把每一个sql语句保存在一个map中,map中的key就是namespace+id,如果key重复,那么就会相互覆盖。
-
Mybatis 映射⽂件中,如果 A 标签通过 include 引⽤了 B 标签的内容,请问,B 标签能否定义在 A 标签的后⾯,还是说必须定义在 A 标签的前⾯?
可以定义在任何地方。MyBatis解析的时候,如果发现没有B标签,那么会跳过A标签标记为未解析,等到全部解析完毕后,再重新解析一遍未解析的标签,这个时候就可以成功了。
-
简述 Mybatis 的 Xml 映射⽂件和 Mybatis 内部数据结构之间的映射关系?
MyBatis将所有的配置信息都保存在一个Configuration对象中。其中:
- parameterMap会被解析为ParameterMap对象,每个子元素被解析为ParameterMapping对象
- resultMap会被解析为ResultMap对象,每个子元素被解析为ResultMapping对象
- 增删改查标签被解析为MappedStatement对象
- 标签内的sql被解析为BoundSql对象
-
为什么说 Mybatis 是半⾃动 ORM 映射⼯具?它与全⾃动的区别在哪⾥?
待完成...