一、什么是Mybatis
-
Mybatis 是一个半 ORM 框架,它内部封装了JDBC,开发时只需要关心 SQL 语句本身,不需要关心底层的实现。
-
Mybatis 可用 XML 或 注解进行开发和映射原生信息,将 POJO映射成数据库中的记录,避免了几乎所有的JDBC 代码和手动设置参数以及获取结果集
-
通过 XML 文件或注解的方式将要执行的 statement 配置起来,通过 java 对象和 statement 中的sql语句的动态参数进行映射绑定生成最终的 SQL 语句,最后由框架将返回结果进行封装映射成对象进行返回。
二、Mybatis 的优缺点是什么?
优点:
-
基于 SQL 语句编程,相当灵活,不会对应用程序和数据库的现有设计造成影响,SQL 写在XML内减少了与 java 代码的耦合,便于管理,提供了动态标签可以实现动态 SQL 编写。
-
与 JDBC 相比,减少了50%以上的代码量,消除大量冗余代码
-
能与 Spring 很好的集成
-
提供标签映射,支持对象和数据库的ORM字段关系映射
-
支持一对多、多对多查询实现
缺点:
- 需要编写大量的 SQL 语句
三、#{}和${} 的区别是什么
#{}是预编译处理,${} 是字符串替换
Mybatis 处理 #{} 时会将其替换为 ?,调用 PreparedStatement 的 set 方法进行赋值
Mybatis 处理${} 时,就是将其替换成变量的值
#{} 可以有效的防止 SQL注入,提高系统安全性
四、当实体类中的属性和表中的字段不一致时怎么办?
-
通过查询语句设置别名进行映射
-
通过映射字段名和实体名进行映射
五、Mybatis 是如何分页的?分页插件的原理是什么?
Mybatis 使用 RowRounds 对象进行分页,它是针对 ResultsEt 结果集执行的内存分页,非物理分页,可以在 sql 内直接写带有物理分页的参数来完成分页功能,也可以使用分页插件来完成物理分页。
分页插件的原理是使用 Mybatis 提供的插件接口,实现自定义插件,在插件的拦截方法内拦截执行中的 sql,然后加上物理分页的语句,实现分页功能。
六、Mybatis 是如何将 sql 结果封装为目标对象并返回的?都有哪些映射形式?
-
使用标签进行映射,在 ResultMap 中 逐一定义数据库字段名与对象属性名的映射关秀
-
使用 sql 列的别名进行映射
七、Mybatis 实现一对一有几种方式?具体怎么操作
-
有联合查询
-
嵌套查询
联合查询是几个表一起查询,只查询一次,通过 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 的一级缓存、二级缓存
-
一级缓存:基于PrepetualCache 的HashMap 本地缓存,其存储作用域为 Session,当 Session flush 或者 close 之后,该 Session 中的所有 Cache 将会被清空
-
二级缓存:默认采用Perpetuation、HashMap 存储,不同在于其存储的作用于是Mapper(Namespace),并可自定义存储源
默认开启一级缓存
默认不开启二级缓存,需要开启二级缓存可在映射文件中进行配置,并实现Serializable序列化接口