一、底层定位:全自动 ORM vs 半自动 SQL 映射

1. Hibernate(全自动化 ORM 框架)

       ORM:对象关系映射,完全屏蔽 SQL

  • 核心思想:操作 Java 实体对象,框架自动生成 SQL 执行
  • 不用手写大部分增删改查 SQL,只写 HQL/JPQL 面向对象查询语句
  • 封装完整:自动处理表关联、外键、级联操作、事务、缓存

2. MyBatis(半自动化持久层框架)

SQL 映射框架,SQL 控制权交给开发者

  • 核心思想:Java 实体 ↔ 手动编写的 SQL 语句双向绑定
  • 必须自己写 XML / 注解 SQL,框架只负责参数封装、结果集映射
  • 不屏蔽数据库底层,灵活控制 SQL 细节

================================例子====================================

一、先准备统一实体表(两边共用一张 user 表)

数据库表 t_user

CREATE TABLE t_user(
    id INT PRIMARY KEY AUTO_INCREMENT,
    username VARCHAR(20),
    age INT
);

Java 实体类

public class User {
    private Integer id;
    private String username;
    private Integer age;
    // getter/setter
}

二、Hibernate 示例:全自动 ORM,几乎不写 SQL

1. 只需注解映射实体,不用写任何 SQL 文件

@Entity
@Table(name = "t_user")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    private String username;
    private Integer age;
    // getter、setter
}

2. 新增用户:只操作对象,框架自动生成 insert SQL

Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();

User user = new User();
user.setUsername("张三");
user.setAge(20);
session.save(user); // 一行代码,不用写insert语句

tx.commit();
session.close();

底层 Hibernate 自动生成执行 SQL:

insert into t_user (username, age) values (?, ?)

3. 根据 id 查询对象:操作对象,自动 select

User user = session.get(User.class, 1); 
System.out.println(user.getUsername());

自动生成 SQL:

select user0_.id as id1_0_0_, user0_.username as username2_0_0_, user0_.age as age3_0_0_ from t_user user0_ where user0_.id=?

4. 复杂查询写 HQL(面向对象,不是表名)

// 查年龄大于18的用户,写类名User,不是表t_user
String hql = "from User where age > 18";
Query query = session.createQuery(hql);
List<User> list = query.list();

你看不到表、字段,只操作 Java 类和属性;框架内部翻译为原生 SQL 执行。

三、MyBatis 示例:半自动,所有 SQL 必须自己手写

1. Mapper 接口

public interface UserMapper {
    // 新增用户
    int insertUser(User user);
    // 根据id查询
    User selectById(Integer id);
    // 查询18岁以上用户
    List<User> selectOver18();
}

2. 必须手动写 XML,自己写完整 SQL

UserMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mapper.UserMapper">

    <!-- 自己手写insert SQL -->
    <insert id="insertUser">
        insert into t_user(username, age) values(#{username}, #{age})
    </insert>

    <!-- 自己手写select SQL -->
    <select id="selectById" resultType="com.pojo.User">
        select id,username,age from t_user where id = #{id}
    </select>

    <!-- 复杂查询自己写原生SQL,直接操作表t_user -->
    <select id="selectOver18" resultType="com.pojo.User">
        select * from t_user where age > 18
    </select>
</mapper>

3. 调用代码

UserMapper mapper = sqlSession.getMapper(UserMapper.class);
// 新增
User u = new User();
u.setUsername("张三");
u.setAge(20);
mapper.insertUser(u);

// 查询
User user = mapper.selectById(1);
List<User> list = mapper.selectOver18();

MyBatis 做了什么?

你写好完整原生 SQL,MyBatis 只帮你两件事:

  1. 把 Java 对象参数填充到 SQL #{} 占位符
  2. 把数据库查询结果自动封装成 User 实体 (SQL 语句长什么样、怎么联表、加什么索引、分页语法完全由你控制。)

二、开发方式对比

1. Hibernate

  1. 只定义实体类 + 映射文件 / 注解(@Entity),自动映射数据库表
  2. 简单 CRUD 直接调用 API:save()/update()/delete()/get(),无 SQL
  3. 复杂查询写 HQL(面向对象,和数据库无关)或 Criteria 动态查询
  4. 分页、多表关联、批量操作由框架封装

优点:开发速度极快,小型项目少写大量 SQL

缺点:自动生成 SQL 不可控,复杂场景容易产生低效、冗余 SQL

2. MyBatis

  1. 实体 + Mapper 接口 + XML 映射文件,每条业务逻辑对应一条手写 SQL
  2. CRUD 全部手动编写 SQL,支持原生数据库函数、存储过程
  3. 动态 SQL 用<if><where><foreach>标签拼接,灵活定制
  4. 分页、多表联查、性能优化完全由开发人员控制 SQL

优点:SQL 可控,方便调优,适配复杂报表、多表大数据场景 缺点:重复工作量大,简单单表操作也要写大量 XML

三、数据库耦合程度

1.Hibernate 低耦合(跨数据库友好)

  • HQL 不依赖数据库方言,切换 MySQL/Oracle 只需改配置方言
  • 自动适配不同数据库分页、函数语法
  • 适合需要多数据库兼容的系统
  • 代价:底层 SQL 统一封装,会牺牲部分数据库独有特性

2.MyBatis 高耦合(绑定原生 SQL)

  • 直接写原生 SQL,大量使用数据库专属函数、分页语法时切换库要改 SQL
  • 可直接使用数据库特有性能特性(Oracle 序列、MySQL 索引提示)
  • 互联网大数据、金融系统首选,追求 SQL 极致性能

四、缓存机制

1. Hibernate 完整两级缓存

  • 一级缓存(Session 缓存,默认开启) 同一次会话重复查询,直接读取内存,减少 DB 访问
  • 二级缓存(全局 SessionFactory 缓存,可配置 Redis 等) 跨会话共享缓存,适合查询多、修改少的静态数据 缓存全自动管理,无需手动处理缓存失效,但批量更新易出现缓存脏数据。

2. MyBatis 简单两级缓存

  • 一级缓存(SqlSession 缓存,默认开启) 仅当前会话生效,会话关闭缓存清空
  • 二级缓存(Mapper 级别缓存,手动开启) 按 Mapper 文件隔离缓存,颗粒度粗;分布式场景容易脏读 MyBatis 缓存轻量,实际生产中大多直接用 Redis 替代自带二级缓存。

五、表结构操作

  • Hibernate 支持自动建表:配置hibernate.hbm2ddl.auto可自动创建 / 更新表结构,快速搭建测试环境;生产不推荐自动更新表。
  • MyBatis 无自动建表能力,表结构必须手动执行 SQL 脚本创建。

六、适用场景

选 Hibernate / JPA(Spring Data JPA 底层就是 Hibernate)

  • 中小型内部管理系统、后台 CRUD 系统
  • 业务简单、单表多、关联少,追求快速开发
  • 产品需要兼容多种数据库
  • 迭代快、SQL 简单,无复杂统计报表

选 MyBatis(主流互联网框架)

  • 互联网高并发、大数据量系统(电商、支付、股票、大数据报表)
  • 复杂多表联查、统计分析、海量分页
  • 需要精细 SQL 调优、索引优化、存储过程
  • 团队 DBA 严格管控 SQL,要求所有 SQL 可审计
  • 仅使用单一数据库,不需要跨库兼容

七、简短总结对照表

维度 Hibernate(JPA) MyBatis
SQL 编写 自动生成,少手写 全部手动编写
开发效率 高,简单业务超快 偏低,重复 SQL 多
SQL 可控性 弱,难优化慢 SQL 强,自由调优
数据库兼容性 好,切换库改动小 差,换库需改 SQL
缓存 完整两级缓存,自动管理 简易缓存,分布式慎用
学习成本 高(理解持久态、缓存、级联) 低,只需懂 SQL + 基础映射
行业使用 传统 ERP、后台管理系统 互联网、高并发、金融项目

补充:Spring Data JPA

现在很少直接裸用 Hibernate,大多封装为 Spring Data JPA,底层仍是 Hibernate;而 MyBatis 对应封装为 MyBatis-Plus,提供单表自动 CRUD,弥补 MyBatis 单表写 SQL 麻烦的短板。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐