跳到主要内容

与其他框架对比

性能、易用性、可控性三维对比

对比概览

维度MyBatisMyBatisGXMyBatis-PlusJPA
性能⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
易用性⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
可控性⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐

性能维度

MyBatisGX 优势

┌─────────────────────────────────────────────────────────────────┐
│ SQL 预生成机制 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 启动阶段 运行阶段 │
│ ┌─────────────┐ ┌─────────────┐ │
│ │ 扫描 DAO │ │ │ │
│ │ 解析方法名 │ ───────────▶ │ 直接执行 │ │
│ │ 生成 XML │ │ 无额外开销 │ │
│ └─────────────┘ └─────────────┘ │
│ │
│ vs JPA 运行时反射/脏检查/自动 Flush │
│ │
└─────────────────────────────────────────────────────────────────┘
对比项MyBatisGXJPA
SQL 生成时机启动时预生成运行时动态生成
运行时反射
脏检查
自动 Flush
持久化上下文

关联查询性能

抓取模式说明适用场景
SIMPLE简单查询,存在 N+1 问题数据量小
BATCH批量查询,N+1 → 1+M默认推荐
JOIN联表查询,1+1 模式结果集小
NONE不抓取,完全手动控制缓存/分离数据源

易用性维度

代码量对比

原生 MyBatis

<!-- 需要编写 XML -->
<select id="findByNameAndAge" resultType="User">
SELECT * FROM user
WHERE name = #{name} AND age = #{age}
</select>

MyBatis-Plus

// Service 层拼装条件
userMapper.selectList(
new LambdaQueryWrapper<User>()
.eq(User::getName, name)
.eq(User::getAge, age)
);

JPA

// Specification 拼装
Specification<User> spec = (root, query, cb) -> {
List<Predicate> predicates = new ArrayList<>();
predicates.add(cb.equal(root.get("name"), name));
predicates.add(cb.equal(root.get("age"), age));
return cb.and(predicates.toArray(new Predicate[0]));
};

MyBatisGX

// 方法名即查询
List<User> findByNameAndAge(String name, Integer age);

查询实体解耦

MyBatisGX 通过 QueryEntity 将查询条件从 Service 层解耦:

// 查询条件封装在 QueryEntity 中
@QueryEntity(User.class)
public class UserQuery extends User {
private String nameLike;
private Integer ageGt;
private List<Long> idIn;
}

// Service 层只负责业务流程
public List<User> searchUsers(UserQuery query) {
return userDao.findList(query);
}

可控性维度

SQL 可见性

框架SQL 可见性说明
MyBatis完全可见XML 中明确定义
MyBatisGX完全可见启动时生成 XML,可查看
MyBatis-Plus部分可见Wrapper 动态构建
JPA不可见运行时生成,难以预测

SQL 覆盖机制

MyBatisGX 的优先级机制确保可控性:

┌─────────────────────────────────────────────────────────────────┐
│ SQL 优先级 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ mapper.xml 定义 ───────────────────────────▶ 最高优先级 │
│ ↓ │
│ @Statement 注解 ───────────────────────────▶ 次高优先级 │
│ ↓ │
│ 实体/QueryEntity 字段 ────────────────────▶ 中等优先级 │
│ ↓ │
│ 方法名派生 ──────────────────────────────▶ 默认行为 │
│ │
│ 任何级别都可以被上级覆盖,SQL 始终可控 │
│ │
└─────────────────────────────────────────────────────────────────┘

无隐式行为

行为MyBatisGXJPA
隐式 SQL 执行❌ 无✅ 有
自动脏检查❌ 无✅ 有
延迟加载触发显式调用可能隐式触发
事务 Flush手动控制自动 Flush

选择建议

选择 MyBatisGX 如果你:

  • 需要减少样板代码,但不想牺牲 SQL 可控性
  • 希望查询逻辑收敛在 DAO 层,不侵入 Service 层
  • 需要声明式关联查询,但不想引入 JPA 的复杂性
  • 希望在 AI 时代减少代码量,降低上下文负担

选择 MyBatis 如果你:

  • 需要绝对控制每一条 SQL
  • 项目简单,不需要 ORM 增强

选择 MyBatis-Plus 如果你:

  • 习惯 Wrapper 方式构建查询
  • 已有项目生态

选择 JPA 如果你:

  • 完全面向对象建模
  • 可以接受黑盒运行时