跳到主要内容

ORM 框架对比

问题

不同编程语言生态下的主流 ORM 框架如何选型?

答案

一、Node.js/TypeScript 生态 ORM

这是前端/全栈开发者最常接触的 ORM 生态。

维度PrismaTypeORMDrizzleSequelize
首发年份2019201620222014
Schema 定义.prisma DSLTS 装饰器TS 函数JS 对象 / TS 装饰器
API 风格声明式对象Repository + QBSQL-like 函数方法链
类型安全⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
迁移工具Prisma Migrate内置drizzle-kitsequelize-cli
关系加载显式 include懒/急加载with / JOINinclude(急加载)
N+1 风险低(无懒加载)高(默认懒加载)
Edge 兼容部分支持不支持完全支持不支持
Bundle 大小~400KB~800KB~50KB~500KB
数据库PG/MySQL/SQLite/MongoDBPG/MySQL/SQLite/MSSQL/MongoDBPG/MySQL/SQLitePG/MySQL/SQLite/MSSQL

二、Java 生态 ORM

维度MyBatisMyBatis-PlusJPA/HibernateSpring Data JPA
类型半自动 ORMMyBatis 增强全自动 ORMJPA + Spring 封装
SQL 控制手写 XML/注解 SQL自动 CRUD + 手写JPQL / HQL方法名推导查询
N+1手动控制手动控制配置 fetch 策略@EntityGraph
学习成本
灵活性高(完全控制 SQL)
适合场景复杂 SQL、DBA 友好快速 CRUD领域驱动设计Spring Boot 快速开发
Java ORM 选型建议
  • 国内企业:MyBatis / MyBatis-Plus(90%+ 占比)
  • 复杂业务查询:MyBatis(SQL 精确控制)
  • 快速 CRUD:MyBatis-Plus
  • DDD 架构:JPA / Hibernate

三、Python 生态 ORM

维度SQLAlchemyDjango ORMTortoise ORMSQLModel
类型Core + ORMFull-stack ORMAsync ORMSQLAlchemy + Pydantic
异步支持是(2.0+)有限完全异步
框架绑定Django 专属无(FastAPI 推荐)
查询 APICore 表达式 / ORMQuerySet 链类 DjangoSQLAlchemy 风格

四、Go 生态 ORM

维度GORMsqlxEntsqlc
类型全功能 ORMSQL 工具库代码生成 ORMSQL → Go 代码生成
类型安全中(反射)低(手动映射)高(代码生成)高(编译时检查)
性能中(反射开销)高(接近原生)
适合场景快速开发性能敏感图关系、复杂模型SQL 精确控制

五、跨语言 ORM 通用对比维度

选型时应考虑以下维度:

维度说明权重
类型安全查询/结果是否编译时检查
SQL 控制力能否精确控制生成的 SQL
N+1 防护是否容易产生 N+1 问题
迁移工具Schema 变更管理是否方便
性能对象映射的运行时开销
学习成本上手难度
生态成熟度社区、插件、文档
框架集成与主流 Web 框架配合

常见面试问题

Q1: ORM vs 原始 SQL,如何选择?

答案

场景选择原因
标准 CRUDORM开发效率高、类型安全
复杂报表查询原始 SQL多表 JOIN、窗口函数、子查询
批量数据操作原始 SQL避免 ORM 逐条对象化的开销
快速原型ORM自动建表、迁移
极致性能原始 SQL消除 ORM 运行时开销

最佳实践:以 ORM 为主,复杂查询用原始 SQL 逃逸

Q2: 为什么 Prisma 和 Drizzle 不支持懒加载?

答案

这是有意为之的设计决策

  1. 懒加载是 N+1 问题的根源,关联属性被隐式访问时自动触发查询
  2. 显式 include / with 让开发者清楚知道加载了哪些数据
  3. 没有隐式查询意味着 SQL 数量完全可预测
  4. 更适合无状态的 Web 请求模型(不需要 Session/Unit of Work)

Q3: MyBatis 为什么在国内比 JPA 更流行?

答案

  1. SQL 控制力:国内项目对 SQL 调优要求高,MyBatis 让 DBA 能直接审查 SQL
  2. 学习成本:MyBatis 概念简单(SQL + 映射),JPA(Hibernate)概念复杂(一级缓存、二级缓存、Session 管理、JPQL)
  3. 复杂查询:多表关联、动态条件在 MyBatis 的 XML 中更直观
  4. 历史原因:iBatis(MyBatis 前身)在国内早期就有大量使用

Q4: 如何衡量 ORM 的性能开销?

答案

ORM 的开销主要在:

  1. 对象映射:将数据库行转换为应用对象(反射 / 代码生成)
  2. 查询构建:将链式 API 转换为 SQL
  3. 变更追踪:某些 ORM(如 Hibernate)跟踪对象状态
  4. 连接管理:连接池获取和释放

优化手段:

  • 使用 select 只查需要的字段
  • 批量操作用原始 SQL
  • 关闭不必要的变更追踪(如 Hibernate 的 readOnly 事务)
  • 使用代码生成型 ORM(如 Drizzle、sqlc)减少反射开销

相关链接