java 开发之 Mybatis 快问快答
1.Mybatis 的一级、二级缓存
(1)一级缓存: 基于 PerpetualCache 的 HashMap 本地缓存,其存储作用域为 Session,当 Session flush 或 close 之后,该 Session 中的所有 Cache 就将清空,默认打开一级缓存。
(2)二级缓存与一级缓存其机制相同,默认也是采用 PerpetualCache,HashMap 存储,不 同在于其存储作用域为 Mapper(Namespace),并且可自定义存储源,如 Ehcache。默认不 打开二级缓存,要开启二级缓存,使用二级缓存属性java培训类需要实现 Serializable 序列化接口(可用 来保存对象的状态),可在它的映射文件中配置 ;
(3)对于缓存数据更新机制,当某一个作用域(一级缓存 Session/二级缓存 Namespaces)的 进行了 C/U/D 操作后,默认该作用域下所有 select 中的缓存将被 clear 掉并重新更新,如果开 启了二级缓存,则只根据配置判断是否刷新。
![](https://static001.geekbang.org/infoq/5d/5dc26f0bedf7bbf86fce41f107673e94.png)
2.Mybatis 都有哪些 Executor 执行器?它们之间的区别是什么?
Mybatis 有三种基本的 Executor 执行器,SimpleExecutor、ReuseExecutor、 BatchExecutor。
SimpleExecutor:每执行一次 update 或 select,就开启一个 Statement 对象,用完立刻关闭 Statement 对象。
ReuseExecutor:执行 update 或 select,以 sql 作为 key 查找 Statement 对象,存在就使用, 不存在就创建,用完后,不关闭 Statement 对象,而是放置于 Map<String, Statement>内, 供下一次使用。简言之,就是重复使用 Statement 对象。
BatchExecutor:执行 update(没有 select,JDBC 批处理不支持 select),将所有 sql 都添加 到批处理中(addBatch()),等待统一执行(executeBatch()),它缓存了多个 Statement 对象,每个 Statement 对象都是 addBatch()完毕后,等待逐一执行 executeBatch()批处理。与 JDBC 批处理相同。
作用范围:Executor 的这些特点,都严格限制在 SqlSession 生命周期范围内。
3.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()方法的调用。这就是延迟加载的基本原理。
当然了,不光是 Mybatis,几乎所有的包括 Hibernate,支持延迟加载的原理都是一样的。
4.Mybatis 能执行一对一、一对多的关联查询吗?都有哪些实现方式,以及它们之间的区别。
答:能,Mybatis 不仅可以执行一对一、一对多的关联查询,还可以执行多对一,多对多的关 联查询,多对一查询,其实就是一对一查询,java培训只需要把 selectOne()修改为 selectList()即可;多对多查询,其实就是一对多查询,只需要把 selectOne()修改为 selectList()即可。
关联对象查询,有两种实现方式,一种是单独发送一个 sql 去查询关联对象,赋给主对象, 然后返回主对象。另一种是使用嵌套查询,嵌套查询的含义为使用 join 查询,一部分列是 A 对 象的属性值,另外一部分列是关联对象 B 的属性值,好处是只发一个 sql 查询,就可以把主对象 和其关联对象查出来。
那么问题来了,join 查询出来 100 条记录,如何确定主对象是 5 个,而不是 100 个?其去重 复的原理是 resultMap 标签内的 id 子标签,指定了唯一确定一条记录的 id 列,Mybatis 根据 id 列值来完成 100 条记录的去重复功能, id 可以有多个,代表了联合主键的语意。
同样主对象的关联对象,也是根据这个原理去重复的,尽管一般情况下,只有主对象会有 重复记录,关联对象一般不会重复。
5.Mybatis 全局配置文件中有哪些标签?分别代表什么意思?
configuration 配置
properties 属性:可以加载 properties 配置文件的信息
settings 设置:可以设置 mybatis 的全局属性
typeAliases 类型命名
typeHandlers 类型处理器
objectFactory 对象工厂
plugins 插件
environments 环境
environment 环境变量
transactionManager 事务管理器
dataSource 数据源
mappers 映射器
6.说一下 resultMap 和 resultType?
resultmap 是手动提交,人为提交,resulttype 是自动提交 MyBatis 中在查询进行 select 映射的时候,返回类型可以用 resultType,也可以用 resultMap,resultType 是直接表示返回类型的,而 resultMap 则是对外部 ResultMap 的引 用,但是 resultType 跟 resultMap 不能同时存在。
在 MyBatis 进行查询映射时,其实查询出来的每一个属性都是放在一个对应的 Map 里面的,其 中键是属性名,值则是其对应的值。
1.当提供的返回类型属性是 resultType 时,MyBatis 会将 Map 里面的键值对取出赋给 resultType 所指定的对象对应的属性。所以其实 MyBatis 的每一个查询映射的返回类型都是 ResultMap,只是当提供的返回类型属性是 resultType 的时候,MyBatis 对自动的给把对应 的值赋给 resultType 所指定对象的属性。
2.当提供的返回类型是 resultMap 时,因为 Map 不能很好表示领域模型,就需要自己再进一步 的把它转化为对应的对象,这常常在复杂查询中很有作用。
7.Mybatis 动态 SQL?
传统的 JDBC 的方法,在组合 SQL 语句的时候需要去拼接,稍微不注意就会少少了一个空 格,标点符号,都会导致系统错误。Mybatis 的动态 SQL 就是为了解决这种问题而产生的;Mybatis 的动态 SQL 语句值基于 OGNL 表达式的,方便在 SQL 语句中实现某些逻辑;可以使用 标签组合成灵活的 sql 语句,提供开发的效率。
Mybatis 的动态 SQL 标签主要由以下几类:If 语句(简单的条件判断) Choose(when/otherwise),相当于 java 语言中的 switch,与 jstl 中 choose 类似 Trim(对包含 的内容加上 prefix,或者 suffix) Where(主要是用来简化 SQL 语句中 where 条件判断,能智能 的处理 and/or 不用担心多余的语法导致的错误) Set(主要用于更新时候) Foreach(一般使用在 mybatis in 语句查询时特别有用)
8.Mybatis 的 Xml 映射文件中,不同的 Xml 映射文件,id 是否可以重复?
不同的 Xml 映射文件,如果配置了 namespace,那么 id 可以重复;如果没有配置 namespace,那么 id 不能重复
9.如何获取自动生成的(主)键值?
10.Mybatis 是如何将 sql 执行结果封装为目标对象并返回的?都有哪些映射形式?
第一种是使用 resultMap 标签,逐一定义数据库列名和对象属性名之间的映射关系。
第二种是使用 sql 列的别名功能,将列的别名书写为对象属性名。
有了列名与属性名的映射关系后,Mybatis 通过反射创建对象,同时使用反射给对象的属性逐 一赋值并返回,那些找不到映射关系的属性,是无法完成赋值的。
11.当实体类的属性名和表种字段名不一致怎么办?
有两种解决方案:可以在 sql 语句给字段名取别名,别名于实体类属性名同名,也可以用 resultMap 来映射字段名和实体类属性名一一对应
12.#{}和 ${}的区别是什么?
{}是预编译处理,${}是字符串替换。
Mybatis 在处理 #{}时,会将 sql 中的 #{}替换为?号,调用 PreparedStatement 的 set 方法来赋 值;
Mybatis 在处理{}时,就是把时,就是把{}替换成变量的值。
使用 #{}可以有效的防止 SQL 注入,提高系统安全性。
13.Mybatis 使用场合?
专注于 sql 本身,是一个足够灵活的 dao 层解决方案.,对性能的要求很高,或者需求多变的项目
14.Mybatis 的优缺点?
Mybaits 的优点:
(1)基于 SQL 语句编程,相当灵活,不会对应用程序或者数据库的现有设计造成任何影响, SQL 写在 XML 里,解除 sql 与程序代码的耦合,便于统一管理;提供 XML 标签,支持编写动态 SQL 语句,并可重用。
(2)与 JDBC 相比,减少了 50%以上的代码量,消除了 JDBC 大量冗余的代码,不需要手动开关连接;
(3)很好的与各种数据库兼容(因为 MyBatis 使用 JDBC 来连接数据库,所以只要 JDBC 支持的 数据库 MyBatis 都支持)。
(4)能够与 Spring 很好的集成;
(5)提供映射标签,支持对象与数据库的 ORM 字段关系映射;提供对象关系映射标签,支持对象关系组件维护。
MyBatis 框架的缺点:
(1)SQL 语句的编写工作量较大,尤其当字段多、关联表多时,对开发人员编写 SQL 语句的功 底有一定要求。
(2)SQL 语句依赖于数据库,导致数据库移植性差,不能随意更换数据库。
MyBatis 框架适用场合:
(1)MyBatis 专注于 SQL 本身,是一个足够灵活的 DAO 层解决方案。
(2)对性能的要求很高,或者需求变化较多的项目,如互联网项目,MyBatis 将是不错的选 择。
15.什么是 Mybatis?
1)mybatis 是一个半 ORM 框架,它内部封装了 JDBC,开发时只需要关乎 sql 语句本身,不需 要花费精力去处理驱动,创建连接,创建 1statement 等繁复过程。
2)mybatis 可以使用 xml 或注解来配置和映射原生信息。将 pijo 映射成数据库中的记录,避免 了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。
3)通过 xm 文件或注解的方式将要执行的各种 statement 配置起来,并通 java 对象和 statement 中 sql 的动态参数进行映射生成最终的 sql 语句,最后由 mybatis 框架执行 sql 并将结果映射 java 对象返回.
文章来源数据结构与算法
评论