mybatis面经题

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

    ${}

      表示拼接sql串

      通过${}可以将parameterType 传入的内容拼接在sql中且不进行jdbc类型转换

      ${}可以接收简单类型值或pojo属性值

      如果parameterType传输单个简单类型值,${}括号中只能是value

      ${} 注入什么就是什么,且如果是简单类型的值需要用 value 来接收

    

 

 

 

     #{}

      表示一个占位符号,通过#{}可以实现preparedStatement向占位符中设置值

      自动进行java类型和jdbc类型转换

      #{}可以有效防止sql注入

      #{}可以接收简单类型值或pojo属性值

      如果parameterType传输单个简单类型值,#{}括号中可以是value或其它名称

    

 

     

 

 2.  Xml 映射⽂件中,除了常⻅的 select|insert|updae|delete 标签之外,还有哪些标签

      (61条消息) Mybatis mapper.xml标签详解_Java爆肝工程师的博客-CSDN博客

答:还有很多其他的标
签, <resultMap> 、 <parameterMap> 、 <sql> 、 <include> 、 <selectKey> ,加上动态 sql 的 9
个标签, trim|where|set|foreach|if|choose|when|otherwise|bind 等,其中为 sql ⽚段标签,通过
<include> 标签引⼊ sql ⽚段, <selectKey> 为不⽀持⾃增的主键⽣成策略标签。

3. Mybatis 是如何进⾏分⻚的?分⻚插件的原理是什么?

4. Mybatis 执⾏批量插⼊,能返回数据库主键列表吗

  可以

5. Mybatis 动态 sql 是做什么的?都有哪些动态 sql?能简述⼀下动态 sql 的执⾏原理不?

Mybatis 动态 sql 可以让我们在 Xml 映射⽂件内,以标签的形式编写动态 sql,完成逻辑判断和动态拼接 sql 的功能,Mybatis 提供了 9 种动态 sql 标签

trim|where|set|foreach|if|choose|when|otherwise|bind 。其执⾏原理为,使⽤ OGNL 从 sql 参数对象中计算表达式的值,根据表达式的值动态拼接 sql,以此来完成动态 sql 的功能。

6. Mybatis 是如何将 sql 执⾏结果封装为⽬标对象并返回的?都有哪些映射形式?

第⼀种是使⽤ <resultMap> 标签,逐⼀定义列名和对象属性名之间的映射关系。第⼆种是使⽤ sql 列的别名功能,将列别名书写为对象属性名,⽐如 T_NAME AS NAME,对象属性名⼀般是 name,⼩写,但是列名不区分⼤⼩写,Mybatis 会忽略列名⼤⼩写,智能找到与之对应对象属性名,你甚⾄可以写成 T_NAME AS NaMe,Mybatis ⼀样可以正常⼯作。有了列名与属性名的映射关系后,Mybatis 通过反射创建对象,同时使⽤反射给对象的属性逐⼀赋值并返回,那些找不到映射关系的属性,是⽆法完成赋值的。

7. Mybatis 能执⾏⼀对⼀、⼀对多的关联查询吗?都有哪些实现⽅式,以及它们之间的区别。

答:能,Mybatis 不仅可以执⾏⼀对⼀、⼀对多的关联查询,还可以执⾏多对⼀,多对多的关联查询,多对⼀查询,其实就是⼀对⼀查询,只需要把 selectOne() 修改为 selectList() 即可;多对多查询,其实就是⼀对多查询,只需要把 selectOne() 修改为 selectList() 即可。关联对象查询,有两种实现⽅式,⼀种是单独发送⼀个 sql 去查询关联对象,赋给主对象,然后返回主对象。另⼀种是使⽤嵌套查询,嵌套查询的含义为使⽤ join 查询,⼀部分列是 A 对象的属性值,另外⼀部分列是关联对象 B 的属性值,好处是只发⼀个 sql 查询,就可以把主对象和其关联对象查出来。那么问题来了,join 查询出来 100 条记录,如何确定主对象是 5 个,⽽不是 100 个?其去重复的原理是 <resultMap> 标签内的 <id> ⼦标签,指定了唯⼀确定⼀条记录的 id 列,Mybatis 根据列值来完成 100 条记录的去重复功能, <id> 可以有多个,代表了联合主键的语意。同样主对象的关联对象,也是根据这个原理去重复的,尽管⼀般情况下,只有主对象会有重复记录,关联对象⼀般不会重复。

8. 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() ⽅法的调⽤。这就是延迟加载的基本原理

9.Mybatis 的 Xml 映射⽂件中,不同的 Xml 映射⽂件,id 是否可以重复?

答:不同的 Xml 映射⽂件,如果配置了 namespace,那么 id 可以重复;如果没有配置namespace,那么 id 不能重复;毕竟 namespace 不是必须的,只是最佳实践⽽已。原因就是 namespace+id 是作为 Map<String, MappedStatement> 的 key 使⽤的,如果没有namespace,就剩下 id,那么,id 重复会导致数据互相覆盖。有了 namespace,⾃然 id 就可以重复,namespace 不同,namespace+id ⾃然也就不同

10. Mybatis 中如何执⾏批处理

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

12. Mybatis 中如何指定使⽤哪⼀种 Executor 执⾏器

13. Mybatis 是否可以映射 Enum 枚举类?

答:Mybatis 可以映射枚举类,不单可以映射枚举类,Mybatis 可以映射任何对象到表的⼀列上。映射⽅式为⾃定义⼀个 TypeHandler ,实现 TypeHandler 的 setParameter() 和 getResult()接⼝⽅法。 TypeHandler 有两个作⽤,⼀是完成从 javaType ⾄ jdbcType 的转换,⼆是完成jdbcType ⾄ javaType 的转换,体现为 setParameter() 和 getResult() 两个⽅法,分别代表设置sql 问号占位符参数和获取列查询结果。

14. Mybatis 映射⽂件中,如果 A 标签通过 include 引⽤了 B 标签的内容,请问,B 标签能否定义在 A 标签的后⾯,还是说必须定义在 A 标签的前⾯?

答:虽然 Mybatis 解析 Xml 映射⽂件是按照顺序解析的,但是,被引⽤的 B 标签依然可以定义在任何地⽅,Mybatis 都可以正确识别。原理是,Mybatis 解析 A 标签,发现 A 标签引⽤了 B 标签,但是 B 标签尚未解析到,尚不存在,此时,Mybatis 会将 A 标签标记为未解析状态,然后继续解析余下的标签,包含 B 标签,待所有标签解析完毕,Mybatis 会重新解析那些被标记为未解析的标签,此时再解析 A 标签时,B标签已经存在,A 标签也就可以正常解析完成了

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

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

16. 为什么说 Mybatis 是半⾃动 ORM 映射⼯具?它与全⾃动的区别在哪⾥?

答:Hibernate 属于全⾃动 ORM 映射⼯具,使⽤ Hibernate 查询关联对象或者关联集合对象时,可以根据对象关系模型直接获取,所以它是全⾃动的。⽽ Mybatis 在查询关联对象或关联集合对象时,需要⼿动编写 sql 来完成,所以,称之为半⾃动 ORM 映射⼯具。
posted @ 2021-11-04 23:32  微~粒  阅读(100)  评论(0)    收藏  举报