一、核心区别与定位(面试必问)
| 维度 | MyBatis | Hibernate |
|---|---|---|
| 定位 | 半自动ORM框架(SQL需手动写) | 全自动ORM框架(SQL自动生成) |
| 核心思想 | 专注SQL优化,灵活控制查询 | 完全对象化,屏蔽SQL细节 |
| 开发效率 | 简单CRUD慢(需写SQL),复杂查询快(SQL可控) | 简单CRUD快(零SQL),复杂查询慢(调优成本高) |
| 学习成本 | 低(懂SQL即可) | 高(需掌握HQL、缓存、关联映射等) |
| 性能 | 优(SQL手动优化,无额外开销) | 中(自动生成SQL可能冗余,需调优) |
| 适用场景 | 互联网、高并发、复杂查询(如电商、金融) | 企业级应用、简单CRUD(如OA、后台管理系统) |
二、MyBatis 核心考点
1. 核心特性与原理
- 核心:基于XML/注解映射SQL,将SQL与Java代码分离,简化JDBC操作;
- 原理:
- 加载配置文件(mybatis-config.xml + Mapper.xml/注解);
- 创建SqlSessionFactory(工厂模式,读取配置生成);
- 打开SqlSession(会话,封装JDBC连接,非线程安全);
- 获取Mapper接口代理对象(动态代理,无实现类);
- 执行SQL(通过Executor+StatementHandler操作JDBC,结果集映射为Java对象)。
2. 映射配置(核心实战)
- 映射方式:XML映射(<select>/<insert>/<update>/<delete>)、注解映射(@Select/@Insert等);
- 核心标签:
- <resultMap>:自定义结果集映射(解决表字段与Java属性名不一致、关联查询);
- <parameterMap>:参数映射(较少用,推荐直接用#{});
- <sql>:SQL片段复用(<include>引用);
- 参数传递:
-
{}:预编译(占位符?),防SQL注入(推荐);
- ${}:字符串拼接(直接替换),有注入风险(仅用于表名/列名动态拼接);
-
- 结果映射:
- 自动映射:字段名与属性名一致时无需配置;
- 手动映射:<result column="表字段" property="Java属性"/>。
3. 动态SQL(高频考点)
- 核心标签:if(条件判断)、where(自动补where/删多余and/or)、foreach(循环遍历,如in查询)、choose/when/otherwise(分支选择)、set(更新时自动删多余逗号);
- 作用:简化多条件查询、批量操作的SQL拼接,避免手动字符串拼接错误。
4. 缓存机制
- 一级缓存(默认开启,SqlSession级别):
- 同一SqlSession内,相同查询(SQL+参数+RowBounds)直接从缓存取结果,关闭SqlSession后缓存失效;
- 失效场景:执行insert/update/delete、手动clearCache()、SqlSession关闭;
- 二级缓存(Mapper接口级别,需手动开启):
- 配置:mybatis-config.xml中开启<setting name="cacheEnabled" value="true"/>,Mapper.xml中加<cache/>标签;
- 特点:跨SqlSession共享,缓存对象需序列化(实现Serializable);
- 第三方缓存集成:支持EhCache、Redis等(通过<cache type="第三方缓存类"/>配置)。
5. 关联查询(一对一/一对多)
- 一对一:<association property="属性名" javaType="关联对象类型" select="子查询ID" column="关联字段"/>(嵌套查询)或直接JOIN映射;
- 一对多:<collection property="属性名" ofType="集合元素类型" select="子查询ID" column="关联字段"/>;
- 延迟加载:默认关闭,通过<setting name="lazyLoadingEnabled" value="true"/>开启,按需加载关联对象(减少SQL执行)。
6. 核心问题
- SqlSession是否线程安全?:否,需线程私有(如Spring中注入的Mapper是线程安全的,因Spring管理SqlSession生命周期);
- 如何解决字段名与属性名不一致?:用<resultMap>映射、SQL中起别名、开启驼峰命名自动转换(mapUnderscoreToCamelCase=true);
- 批量操作优化:用SqlSession的batch()方法、foreach标签(注意SQL长度限制)、MyBatis-Plus的批量接口。
三、Hibernate 核心考点
1. 核心特性与原理
- 核心:全自动ORM,通过Java对象操作数据库(无需写SQL),遵循JPA规范;
- 原理:
- 加载配置文件(hibernate.cfg.xml + 实体类注解/hibernate.hbm.xml);
- 创建SessionFactory(重量级对象,线程安全,全局唯一);
- 打开Session(轻量级,封装JDBC连接,非线程安全);
- 开启事务(Transaction),通过Session操作实体(save/update/delete/get);
- 自动生成SQL执行,结果映射为Java对象。
2. 核心注解(JPA规范)
- 实体映射:@Entity(标识实体类)、@Table(指定数据库表名);
- 字段映射:@Id(主键)、@GeneratedValue(主键生成策略:IDENTITY自增、SEQUENCE序列、AUTO自动)、@Column(指定字段名、长度、非空等);
- 关联映射(高频):
- 一对一:@OneToOne(如用户-身份证);
- 一对多:@OneToMany(如用户-订单,配合@JoinColumn指定外键);
- 多对一:@ManyToOne(如订单-用户);
- 多对多:@ManyToMany(如学生-课程,需中间表)。
3. 缓存机制(核心调优点)
- 一级缓存(Session级别,默认开启):
- 同一Session内,多次get/load同一主键的对象,仅查询一次数据库;
- 失效场景:Session关闭、clear()/evict()方法、执行update/delete;
- 二级缓存(SessionFactory级别,需配置开启):
- 作用:跨Session共享缓存,减少数据库查询;
- 配置:添加缓存依赖(如EhCache)、hibernate.cfg.xml中开启cache.use_second_level_cache=true;
- 查询缓存(需手动开启):
- 缓存HQL/SQL查询结果,需配合二级缓存使用,通过query.setCacheable(true)启用。
4. 事务与并发
- 事务隔离级别:对应数据库,通过hibernate.connection.isolation配置(如4=REPEATABLE_READ);
- 并发控制:
- 乐观锁:@Version(添加版本号字段,更新时校验版本,避免脏写);
- 悲观锁:通过Query.setLockMode()添加for update锁。
5. HQL与SQL
- HQL(Hibernate Query Language):面向对象查询语言(如from User where name = ?),跨数据库兼容;
- SQL:原生SQL查询,通过createSQLQuery()方法,适合复杂查询(需手动映射结果集);
- 区别:HQL屏蔽数据库差异,SQL灵活但不兼容。
四、高频对比与实战问题
1. MyBatis 与 Hibernate 关键差异深挖
- SQL控制:MyBatis手动写SQL(灵活,可优化),Hibernate自动生成(简化开发,复杂查询难调优);
- 数据库移植:Hibernate跨数据库性强(HQL自动适配),MyBatis需修改SQL(如MySQL与Oracle的语法差异);
- 关联映射:Hibernate自动维护关联关系(如级联保存),MyBatis需手动配置(更可控);
- 学习成本:MyBatis低(依赖SQL基础),Hibernate高(需掌握ORM思想、缓存、关联映射等)。
2. MyBatis 常见问题与优化
- 优化方向:
- 开启二级缓存+第三方缓存(Redis);
- 动态SQL避免冗余;
- 批量操作使用batch模式;
- 避免N+1查询(用JOIN关联查询替代嵌套查询);
- 合理使用resultMap(减少字段冗余);
- 问题排查:
- SQL执行异常:开启日志打印SQL(logImpl=SLF4J),查看参数绑定;
- 性能问题:分析SQL执行计划,优化索引、减少查询字段。
3. Hibernate 常见问题与优化
- 优化方向:
- 合理使用缓存(一级缓存默认开启,二级缓存按需开启);
- 避免懒加载异常(Session关闭前初始化关联对象);
- 批量操作使用bulkUpdate()/bulkDelete();
- 关闭不必要的级联操作(cascade属性按需配置);
- 优化HQL(避免select *,使用分页查询);
- 问题排查:
- 懒加载异常(LazyInitializationException):延长Session生命周期、提前初始化关联对象、关闭延迟加载;
- 性能差:查看自动生成的SQL(开启show_sql=true),优化关联映射、缓存配置。
4. 如何选择ORM框架?
- 选MyBatis:
- 项目需复杂查询、SQL优化;
- 团队熟悉SQL,追求性能;
- 互联网、高并发、大数据量场景;
- 选Hibernate:
- 项目以简单CRUD为主,无需复杂SQL;
- 追求快速开发,减少重复工作;
- 企业级应用、跨数据库需求。
五、核心原则(面试总结)
- 核心区别:MyBatis“半自动”(SQL可控),Hibernate“全自动”(对象化);
- 性能关键:MyBatis优化靠SQL,Hibernate优化靠缓存+关联映射;
- 适用场景:复杂查询选MyBatis,简单CRUD选Hibernate;
- 实战重点:MyBatis的动态SQL、缓存、关联查询;Hibernate的注解映射、缓存、并发控制。