11. MyBatis 能执行一对一、一对多的关联查询吗?都有哪些实现方式,以及它们之间的区别。
是的,MyBatis 支持执行一对一和一对多的关联查询。
-
关联查询的方式:
association
标签用于处理一对一的关系。collection
标签用于处理一对多的关系。
-
实现方式:
- 嵌套查询(Nested Select) :通过在
association
或collection
中定义另一个 SQL 查询来获取关联对象的数据。 - 嵌套结果映射(Nested Result Map):直接在结果集中映射关联对象或集合,避免了额外的查询,但可能需要更复杂的 SQL 和结果映射配置。
- 嵌套查询(Nested Select) :通过在
-
区别:
- 嵌套查询会在主查询的基础上再发起一次查询,适合数据量较小的情况;而嵌套结果映射会一次性从数据库中取出所有需要的数据,适用于关联表数据量较大的情况。
- 嵌套查询可能导致 N+1 查询问题,即对于每条记录都要进行一次关联查询,而嵌套结果映射可以避免这个问题。
12. MyBatis 是否支持延迟加载?如果支持,它的实现原理是什么?
MyBatis 支持延迟加载。
- 实现原理:
- 当使用
LazyLoading
时,MyBatis 不会立即执行关联对象的查询,而是返回一个代理对象。 - 只有当访问到这些关联对象的属性时,才会触发实际的查询操作,从而减少了不必要的数据库交互。
- 需要在 MyBatis 配置文件中启用延迟加载功能,并确保使用的 JDBC 驱动也支持延迟加载。
- 当使用
13. MyBatis 的 xml 映射文件中,不同的 xml 映射文件的 id 是否可以重复?
不可以。
- 在同一个命名空间内的
id
必须是唯一的。如果多个 XML 映射文件属于不同的命名空间,则它们可以拥有相同的id
,因为 MyBatis 使用namespace.id
来唯一标识每个 SQL 语句。
14. MyBatis 都有哪些 Executor 执行器?它们之间的区别是什么?
- SimpleExecutor:每次查询都会创建新的 PreparedStatement 实例。
- ReuseExecutor:重用已有的 PreparedStatement 实例以减少资源开销。
- BatchExecutor:批量执行 SQL 语句,适用于大量插入或更新操作,能显著提高性能。
- CachingExecutor:为其他 Executor 添加二级缓存功能。
15. MyBatis 中如何指定使用哪一种 Executor 执行器?
- 可以在 MyBatis 配置文件中通过
<setting name="defaultExecutorType" value="REUSE"/>
来设置默认的 Executor 类型。 - 也可以在运行时通过
SqlSession.openSession(ExecutorType executorType)
方法动态选择。
16. MyBatis 是否可以映射 Enum 枚举类?
是的,MyBatis 支持枚举类型的映射。
- 可以通过自定义类型处理器(TypeHandler)将数据库中的值转换为 Java 的 Enum 类型。
- MyBatis 内置了一些常见的枚举类型处理器,如
EnumTypeHandler
和EnumOrdinalTypeHandler
。
17. 简述 MyBatis 的 xml 映射文件和 MyBatis 内部数据结构之间的映射关系?
- XML 映射文件定义了 SQL 语句及其参数和结果集的映射规则。
- MyBatis 内部将这些信息解析成相应的 Java 对象,例如 MappedStatement 表示一条 SQL 语句,ParameterMapping 表示参数映射,ResultMap 表示结果映射等。
- 这些内部数据结构用于构建最终执行的 SQL 并处理查询结果。
18. 为什么说 MyBatis 是半自动 ORM 映射工具?它与全自动的区别在哪里?
- 半自动 ORM:MyBatis 提供了基本的对象关系映射功能,但开发者仍然需要编写 SQL 语句,并且可以通过 XML 文件或注解来配置映射关系。
- 全自动 ORM:像 Hibernate 这样的框架则更加自动化,它可以根据实体类自动生成 SQL 语句,并管理事务和会话。
19. Mybatis 的一级、二级缓存?
- 一级缓存(SqlSession 缓存):作用范围限于当前 SqlSession,当同一个 SqlSession 中重复执行相同查询时,会优先从缓存中取数据。
- 二级缓存(Mapper 缓存):跨 SqlSession 的全局缓存,默认情况下,不同 Mapper 的二级缓存是独立的,除非显式配置共享。
20. 简述 Mybatis 的插件运行原理,以及如何编写一个插件
- 插件机制:MyBatis 允许开发人员通过插件扩展其核心功能,比如拦截 SQL 语句的执行过程。
- 编写插件 :需要实现
Interceptor
接口,并使用@Intercepts
和@Signature
注解来指定要拦截的目标方法。 - 注册插件 :在 MyBatis 配置文件中注册插件,或者通过代码方式添加到
Configuration
对象中。