1、什么是 Mybatis?
Mybatis 是一个半 ORM(对象关系映射)框架
,内部封装了 JDBC,开发时只需要关注 SQL 语句本身。不需要花费精力去处理加载驱动、创建连接、创建 statement 等繁杂的过程。程序员直接编写原生态 sql,可以严格控制 sql 执行性能,灵活度高。
MyBatis 可以使用 XML 或注解来配置和映射原生信息。将 POJO 映射成数 据库中的记录。
2、Mybaits 的优点:
基于 SQL 语句编程,相当灵活,同时,SQL 写在 XML 里,解除 sql 与程序代码的耦合,便于统一管理;
提供 XML 标签,支持编写动态 SQL 语句,并可重用。
能够与 Spring 很好的集成;
提供映射标签,支持对象与数据库的 ORM 字段关系映射;提供对象关系映射标签,支持对象关系组件维护。
3、MyBatis 框架的缺点:
SQL 语句的编写工作量较大,尤其当字段多、关联表多时,对开发人员编写 SQL 语句的功底有一定要求。
SQL 语句依赖于数据库,导致数据库移植性差,不能随意更换数据库。
4、MyBatis 与 Hibernate 有哪些不同?
hibernate是一个ORM框架,而MyBatis是半ORM框架;
Hibernate 对象/关系映射能力强,数据库无关性好,对于关系模型要求高的软件,如果用 hibernate 开发可以节省很多代码,提高效率。
5、#{}和${}的区别是什么?
{} 是预编译处理,${} 是字符串替换。
Mybatis 在处理#{}
时,会将 sql 中的#{}
替换为?
号,调用 PreparedStatement 的 set 方法来赋值;
Mybatis 在处理${}
时,就是把${}
替换成变量的值。
使用#{}
可以有效的防止 SQL 注入,提高系统安全性。
6、当实体类中的属性名和表中的字段名不一样 ,怎么办 ?
第 1 种: 通过在查询的 sql 语句中定义字段名的别名,让字段名的别名和实体类的属性名一致。
第 2 种: 通过<resultMap>
来映射字段名和实体类属性名的一一对应的关系。
7、通常一个 Xml 映射文件,都会写一个 Dao 接口与之对应, 请问,这个 Dao 接口的工作原理是什么?Dao 接口里的方法, 参数不同时,方法能重载吗?。
Dao 接口即 Mapper
接口。接口的全限名,就是映射文件中的 namespace
的值;
接口的方法名,就是映射文件中 Mapper 的 Statement
的 id
值;
接口方法内的参数,就是传递给 sql 的参数。
Mapper 接口里的方法,是不能重载的,因为是使用 全限名+方法名 的保存和寻找策略。Mapper 接口的工作原理是 JDK 动态代理,Mybatis 运行时会使用 JDK 动态代理为 Mapper 接口生成代理对象 proxy,代理对象会拦截接口方法,转而执行 MapperStatement
所代表的 sql,然后将 sql 执行结果返回。
8、Mybatis 是如何进行分页的?分页插件的原理是什么?
Mybatis 使用 RowBounds
对象进行分页,它是针对 ResultSet
结果集执行的内存分页,而非物理分页。可以在 sql 内直接书写带有物理分页的参数来完成物理分页功能,也可以使用分页插件来完成物理分页。
分页插件的基本原理是使用 Mybatis 提供的插件接口,实现自定义插件,在插件的拦截方法内拦截待执行的 sql,然后重写 sql,根据 dialect 方言,添加对应的物理分页语句和物理分页参数。
9、Mybatis 动态 sql 有什么用?执行原理?有哪些动态 sql
Mybatis 动态 sql 可以在 Xml 映射文件内,以标签的形式编写动态 sql,执行原理 是根据表达式的值 完成逻辑判断并动态拼接 sql 的功能。
Mybatis 提供了 9 种动态 :
sql 标签:trim | where | set | foreach | if | choose | when | otherwise | bind。
10、Mybatis 的 Xml 映射文件中,不同的 Xml 映射文件,id 是否可以重复?
不同的 Xml 映射文件,如果配置了 namespace
,那么 id 可以重复;
如果没有配置 namespace
,那么 id 不能重复;
理由:
namespace+id
是作为 Map<String, MapperStatement>
的 key 使用的,如果没有 namespace
,就剩下 id,那么,id 重复会导致数据互相覆盖。 有了 namespace,自然 id 就可以重复,namespace 不同,namespace+id 自然 也就不同。
11、为什么说 Mybatis 是半自动 ORM 映射工具?它与全自动 的区别在哪里?
Hibernate 属于全自动 ORM 映射工具,使用 Hibernate 查询关联对象或者关联集合对象时,可以根据对象关系模型直接获取,所以它是全自动的。
而 Mybatis 在查询关联对象或关联集合对象时,需要手动编写 sql 来完成,所以,称之为半自 动 ORM 映射工具。
12、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() 方法的调用。
13、Mybatis 的一级、二级缓存:
1)一级缓存:
基于 PerpetualCache 的 HashMap 本地缓存,其存储作用域为 Session
,当 Session flush 或 close 之后,该 Session 中的所有 Cache 就 将清空,默认打开一级缓存。
2)二级缓存与一级缓存其机制相同:
默认也是采用 PerpetualCache,HashMap 存储,不同在于其存储作用域Mapper(Namespace)
,并且可自定义存储源, 如 Ehcache。默认不打开二级缓存,要开启二级缓存,使用二级缓存属性类需要实现 Serializable
序列化接口(可用来保存对象的状态),可在它的映射文件中配置 <cache/>
;
14、什么是 MyBatis 的接口绑定?有哪些实现方式?
接口绑定:
就是在 MyBatis 中任意定义接口,然后把接口里面的方法和 SQL 语句绑定,我们直接调用接口方法就可以,这样比起原来了SqlSession提供的方法我们可以有更加灵活的选择和设置。
接口绑定有两种实现方式:
- 通过注解绑定:就是在接口的方法上面加上
@Select、@Update
等注解,里面包含 Sql 语句来绑定。 - 通过 xml 里面写 SQL 来绑定: 在这种情况下,要指定 xml 映射文件里面的 namespace 必须 为接口的
全路径名
。当 Sql 语句比较简单时候,用注解绑定, 当 SQL 语句比较复杂 时候,用 xml 绑定,一般用 xml 绑定的比较多。
15、什么是数据持久化?
数据持久化是将内存中的数据模型转换为存储模型,以及将存储模型转换为内存中的数据模型的统称。例如,文件的存储、数据的读取等都是数据持久化操作。数据模型可以是任何数据结构或对象的模型、XML、二进制流等。 当我们编写应用程序操作数据库,对表数据进行增删改查的操作的时候就是数据持久化的操作。