记Mybatis面试篇

994 阅读4分钟

一、什么是Mybatis

  1. Mybatis 是一个半 ORM 框架,它内部封装了JDBC,开发时只需要关心 SQL 语句本身,不需要关心底层的实现。

  2. Mybatis 可用 XML 或 注解进行开发和映射原生信息,将 POJO映射成数据库中的记录,避免了几乎所有的JDBC 代码和手动设置参数以及获取结果集

  3. 通过 XML 文件或注解的方式将要执行的 statement 配置起来,通过 java 对象和 statement 中的sql语句的动态参数进行映射绑定生成最终的 SQL 语句,最后由框架将返回结果进行封装映射成对象进行返回。

二、Mybatis 的优缺点是什么?

优点:

  • 基于 SQL 语句编程,相当灵活,不会对应用程序和数据库的现有设计造成影响,SQL 写在XML内减少了与 java 代码的耦合,便于管理,提供了动态标签可以实现动态 SQL 编写。

  • 与 JDBC 相比,减少了50%以上的代码量,消除大量冗余代码

  • 能与 Spring 很好的集成

  • 提供标签映射,支持对象和数据库的ORM字段关系映射

  • 支持一对多、多对多查询实现

缺点:

  • 需要编写大量的 SQL 语句

三、#{}和${} 的区别是什么

#{}是预编译处理,${} 是字符串替换

Mybatis 处理 #{} 时会将其替换为 ?,调用 PreparedStatement 的 set 方法进行赋值

Mybatis 处理${} 时,就是将其替换成变量的值

#{} 可以有效的防止 SQL注入,提高系统安全性

四、当实体类中的属性和表中的字段不一致时怎么办?

  1. 通过查询语句设置别名进行映射

  2. 通过映射字段名和实体名进行映射

五、Mybatis 是如何分页的?分页插件的原理是什么?

Mybatis 使用 RowRounds 对象进行分页,它是针对 ResultsEt 结果集执行的内存分页,非物理分页,可以在 sql 内直接写带有物理分页的参数来完成分页功能,也可以使用分页插件来完成物理分页。

分页插件的原理是使用 Mybatis 提供的插件接口,实现自定义插件,在插件的拦截方法内拦截执行中的 sql,然后加上物理分页的语句,实现分页功能。

六、Mybatis 是如何将 sql 结果封装为目标对象并返回的?都有哪些映射形式?

  1. 使用标签进行映射,在 ResultMap 中 逐一定义数据库字段名与对象属性名的映射关秀

  2. 使用 sql 列的别名进行映射

七、Mybatis 实现一对一有几种方式?具体怎么操作

  1. 有联合查询

  2. 嵌套查询

联合查询是几个表一起查询,只查询一次,通过 ResultMap 配置 association 配置一个一对一的类来实现

嵌套查询是先查询一个表再根据表的关联关系,去另外一个表查询数据 通过 ResultMap 配置 association 并设置查询条件进行查询

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

Mybatis 仅支持association 和collection 关联集合对象的延迟加载,在 Mybatis 配置文件中设置 lazyLoadingEnable=true | false

原理是:通过cglib创建目标对象的代理对象,当调用目标方法时,进入拦截器方法。

例如:

a.getB().getName(),拦截器 invoke() 方法发现a.getB() 为NULL时,会单独发送事先保存好的查询关联对象的 sql,把 B 查询上来,然后调用 a.getB(b) ,于是 b 对象就有了值,接着完成 a.getB().getName() 方法的调用。

九、Mybatis 的一级缓存、二级缓存

  1. 一级缓存:基于PrepetualCache 的HashMap 本地缓存,其存储作用域为 Session,当 Session flush 或者 close 之后,该 Session 中的所有 Cache 将会被清空

  2. 二级缓存:默认采用Perpetuation、HashMap 存储,不同在于其存储的作用于是Mapper(Namespace),并可自定义存储源

默认开启一级缓存

默认不开启二级缓存,需要开启二级缓存可在映射文件中进行配置,并实现Serializable序列化接口