JDBC、MyBatis 与 JPA:职责与选型比较
比较三种数据库访问方式的抽象层次、SQL 控制能力和典型适用场景。
阅读设置
三者处于不同抽象层
JDBC 是 Java 数据库连接 API;MyBatis 主要将 SQL、参数和结果映射到对象;JPA 是对象关系映射规范,Hibernate 是常见实现。Spring Data JPA 在 JPA 之上提供 Repository 等便利抽象,并不等同于 JPA 本身。
| 维度 | JDBC | MyBatis | JPA / Hibernate |
|---|---|---|---|
| SQL | 手写 SQL | 手写 SQL 与映射 | 常见操作可生成 SQL,也支持查询语言和原生 SQL |
| 资源管理 | 手动或由框架辅助 | 框架管理 Session 等资源 | 持久化上下文与实体生命周期 |
| 适用重点 | 底层控制、理解连接与事务 | SQL 复杂、希望明确控制查询 | 领域实体与常规数据访问 |
| 学习难点 | 资源关闭、异常和事务边界 | 映射、动态 SQL、分页与缓存 | 关联加载、脏检查、N+1 与上下文 |
不能按“JDBC 最高、MyBatis 次之、JPA 最低”直接给性能排序。索引、查询数量、连接池、批处理、事务范围和访问模式往往更重要,应根据实际负载测量。
JDBC 基础示例
String sql = "SELECT id, user_name FROM users WHERE id = ?";
try (Connection connection = dataSource.getConnection();
PreparedStatement statement = connection.prepareStatement(sql)) {
statement.setLong(1, userId);
try (ResultSet result = statement.executeQuery()) {
if (result.next()) {
long id = result.getLong("id");
String name = result.getString("user_name");
// 映射为业务对象
}
}
}
预编译参数适用于值,不适用于任意表名、列名或排序表达式;动态标识符仍需明确白名单。框架托管事务时,应遵循该框架的连接管理方式。
MyBatis 与 JPA 的关注点
MyBatis 适合直接查看和调优 SQL,但仍要处理结果映射、分页和事务。JPA 可以减少常规 CRUD 代码,却需要理解实体状态与加载行为,不能把生成 SQL 当作无需检查数据库的理由。
两者都可能使用缓存;缓存是否开启、作用域和一致性策略取决于实现与配置。跨数据库迁移能力也受实际 SQL、类型和数据库特性影响。
选型顺序
先看团队经验、现有代码和查询复杂度,再做有代表性的读写原型。统一数据访问与事务约定,比单凭框架名判断效率更有价值。