1. Mybatis 是什么?它的核心工作原理是什么?
- 
是什么 :Mybatis 是一个优秀的持久层框架,它避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。它使用简单的 XML 或注解来配置和映射原始类型、Map 和 POJO 到数据库的记录。 
- 
核心原理 :Mybatis 通过 SQL Mapper 机制,将 SQL 语句和 Java 方法进行绑定。开发者只需定义 SQL 语句,Mybatis 就会负责底层与数据库的交互,并将查询结果自动映射为 Java 对象。 
2. 为什么说 Mybatis 是一个半自动化的 ORM 框架?它和 Hibernate 有什么区别?
- 
半自动化 :Mybatis 的 SQL 语句需要开发者手动编写,它只是将 SQL 执行结果自动映射为 Java 对象。它让开发者对 SQL 有完全的控制权。 
- 
区别: - 
SQL 控制:Mybatis 让开发者自由编写 SQL,可以进行 SQL 优化;Hibernate 则是完全的 ORM,它自动生成 SQL,开发者无法直接控制。 
- 
学习成本:Mybatis 简单易学,入门快;Hibernate 概念较多,学习曲线陡峭。 
- 
灵活性:Mybatis 更灵活,适合复杂的、需要手动优化的业务 SQL;Hibernate 适合 CRUD 简单、业务不复杂的场景。 
 
- 
3. Mybatis 的配置文件有哪些?
Mybatis 的核心配置文件主要有两个:
- 
mybatis-config.xml:Mybatis 的全局配置文件,包含了数据库连接、类型别名、插件、映射器(Mapper)等核心配置。
- 
Mapper XML 文件:用于定义 SQL 语句和结果映射的 XML 文件,每个 Mapper 接口通常对应一个 XML 文件。 
4. # 和 $ 符号有什么区别?
- 
#:表示一个预编译参数占位符 。Mybatis 在处理时,会将#替换为?,并使用 PreparedStatement 来执行,可以有效防止 SQL 注入。
- 
$:表示一个字符串占位符 。Mybatis 会直接将$替换为变量的字面量值,不进行预编译。不安全,容易导致 SQL 注入。通常用于动态传入表名或排序列名。
5. 什么是动态 SQL?有哪些常用的标签?
动态 SQL 是 Mybatis 的强大特性,它允许你根据传入的参数,动态地拼接 SQL 语句。
常用的动态 SQL 标签有:
- 
<if>:简单的条件判断。
- 
<choose>,<when>,<otherwise>:类似 Java 的if/else if/else结构。
- 
<where>:自动添加WHERE关键字,并处理 SQL 语句开头多余的AND或OR。
- 
<set>:用于UPDATE语句,自动处理更新字段之间多余的逗号。
- 
<foreach>:用于构建IN语句或批量插入。
6. 如何传递多个参数?
有三种主要方式:
- 
使用 @Param注解:最推荐的方式,清晰直观。Java User selectUser(@Param("name") String name, @Param("age") int age);
- 
使用 Map:将参数放入一个 Map 中,通过键名访问。
- 
使用 JavaBean/POJO:将参数封装成一个 Java 对象,在 XML 中通过对象的属性名访问。 
7. resultType 和 resultMap 的区别?
- 
resultType:用于将查询结果直接映射为简单数据类型 或简单 POJO 对象 。要求数据库列名和 POJO 的属性名完全一致,否则需要使用as别名。
- 
resultMap:用于复杂的自定义映射 。当数据库列名和 POJO 属性名不一致、需要处理复杂关系(如一对一、一对多)或进行复杂数据类型转换时,必须使用resultMap。
8. 如何实现一对一和一对多关系映射?
- 
一对一 :使用 <association>标签。
- 
一对多 :使用 <collection>标签。
这两个标签都可以通过嵌套查询(N+1 问题)或嵌套结果(一次查询解决)两种方式来实现。
9. Mybatis 的缓存机制是怎样的?
Mybatis 提供了两级缓存:
- 
一级缓存(默认开启) : SqlSession级别的缓存。在同一个SqlSession中,如果执行相同的查询,会直接从缓存中获取结果。
- 
二级缓存(默认关闭) : Mapper级别的缓存。多个SqlSession可以共享缓存。需要手动开启。
10. 什么是懒加载(Lazy Loading)?如何配置?
懒加载 也叫延迟加载,指在查询主对象时,不立即查询其关联对象的数据,而是等到真正使用到关联对象时才去查询。这可以避免不必要的数据库查询,减少 N+1 问题。
- 配置 :在 mybatis-config.xml中将lazyLoadingEnabled设置为true。
11. SqlSessionFactory 和 SqlSession 有什么区别?
- 
SqlSessionFactory:是 Mybatis 的核心类,用于创建SqlSession对象。一个应用通常只有一个SqlSessionFactory实例。
- 
SqlSession:是 Mybatis 与数据库交互的会话,包含了所有执行 SQL 的方法。SqlSession不是线程安全的,每次请求都应该新创建一个。
12. 为什么说 Mapper 接口和 Mapper XML 是绑定的?
Mybatis 通过两种方式将它们绑定:
- 
命名空间(Namespace) :XML 文件的 namespace必须是 Mapper 接口的全限定名。
- 
方法名 :XML 文件中 <select>、<insert>等标签的id必须和 Mapper 接口中的方法名一致。
13. Mybatis 如何获取自增主键?
可以使用 <insert> 标签的 useGeneratedKeys 和 keyProperty 属性。
- 
useGeneratedKeys="true":启用获取自增主键的功能。
- 
keyProperty:将自增主键的值设置到 Java 对象的哪个属性中。
14. 什么是 N+1 查询问题?如何解决?
N+1 问题是指,当查询一个主列表时,Mybatis 会先执行一次查询获取主列表,然后针对列表中的每一个 对象,再单独执行一次查询去获取其关联对象,总共需要 1 + N 次查询。
- 
解决方案: - 
使用联结查询 :使用 <association>或<collection>的嵌套结果(Result Map),通过一次JOIN查询获取所有数据。
- 
使用懒加载:如果不需要立即使用关联对象,可以开启懒加载来延迟查询。 
 
- 
15. 解释下 Mybatis 的生命周期对象
- 
SqlSessionFactoryBuilder:构建器,用于从 XML 或 Java 配置中创建SqlSessionFactory,用完即弃。
- 
SqlSessionFactory:会话工厂,用于创建SqlSession。它是线程安全的,通常是单例的。
- 
SqlSession:会话,用于执行 SQL。它不是线程安全的,每次请求都应创建新实例。
- 
Mapper:映射器接口,它的实例由SqlSession创建,用于调用 XML 中定义的 SQL。
16. Mybatis 的 XML 映射文件中 <select> 标签的属性有哪些?
- 
id:映射的 Java 方法名。
- 
parameterType:入参类型。
- 
resultType:返回值类型,简单类型或 POJO。
- 
resultMap:自定义结果集映射。
- 
statementType:可选STATEMENT、PREPARED或CALLABLE,默认为PREPARED。
17. 如何整合 Mybatis 和 Spring?
主要通过 mybatis-spring 模块进行整合。
- 
在 Spring 配置中,配置 SqlSessionFactoryBean,注入数据源和 Mybatis 核心配置文件。
- 
配置 MapperScannerConfigurer或@MapperScan注解,让 Spring 自动扫描 Mapper 接口,并将其注册为 Bean。
18. 为什么要使用 Mybatis?它的优点是什么?
- 
SQL 灵活性:开发者可以完全控制 SQL,方便进行 SQL 优化。 
- 
半自动化:兼顾了 SQL 编写的灵活性和 ORM 框架的自动化映射。 
- 
配置简单:配置相对简单,学习成本低。 
- 
SQL 与代码分离:将 SQL 语句从 Java 代码中解耦,便于维护。 
19. Mybatis 的执行流程是怎样的?
- 
加载 mybatis-config.xml和 Mapper XML 文件,创建SqlSessionFactory。
- 
通过 SqlSessionFactory创建SqlSession。
- 
通过 SqlSession获得 Mapper 接口的代理对象。
- 
调用 Mapper 接口方法。 
- 
代理对象根据方法名,找到对应的 SQL 语句,并执行预编译。 
- 
将参数传入预编译的 SQL 语句。 
- 
执行 SQL,获取结果集。 
- 
Mybatis 将结果集映射到 Java 对象,并返回。 
20. XML 和注解方式映射 SQL,有什么区别?
- 
XML 方式: - 
优点:SQL 和 Java 代码分离,便于维护;支持更复杂的动态 SQL;支持更复杂的映射关系。 
- 
缺点:工作量大,需要维护两个文件。 
 
- 
- 
注解方式: - 
优点:简单,不需要 XML 文件,适用于简单的 SQL。 
- 
缺点:不支持复杂的动态 SQL 和映射关系,代码和 SQL 耦合在一起。 
 
- 
总结 :通常在项目中,对于简单的 CRUD 和单表查询,可以使用注解。对于复杂的、需要动态 SQL 和联结查询的,则必须使用 XML。