性能对比
本页给出 huiche 与主流 Java 数据访问层的 JMH 吞吐对比:10 套访问层 × 6 个场景 × 3 个数据库环境。 只呈现吞吐量(ops/s)与相对原生 JDBC 的倍数,倍数越接近 1.00× 表示越贴近裸 JDBC 的上限。
测试方法
| 项目 | 说明 |
|---|---|
| 基准框架 | JMH 1.37 |
| 预热与测量 | 多轮预热后多次迭代取结果;ORM 类框架需要充分预热,否则会显著低估 |
| 数据源 | 各访问层共享同一 DataSource 与同一张表,每轮迭代前重置数据,保证可比 |
| 数据库 | H2 2.5.252 内存库 / PostgreSQL 17.7 / MySQL 26.10.0 |
| 连接 | HikariCP |
| 对比对象 | 原生 JDBC、MyBatis 3.5.19、Hibernate 7.4、jOOQ 3.21.9、QueryDSL 5.1.0、MyBatis-Flex 1.11.8、MyBatis-Plus 3.5.18、easy-query 3.3.1、Jimmer 0.12.4 |
| 场景 | 单条插入、批量插入 100 条、按主键查 1 条、条件查 100 行、按主键更新 1 条、按主键删除 1 条 |
如何看这些数字
所有访问层跑在同一台机器、同一个数据库实例、同一张表上,因此横向对比是有效的。 但绝对数值受硬件与数据库调优影响很大,未记录具体机型配置,故不建议把 ops/s 当作跨环境的通用指标, 只看"相对原生 JDBC 的倍数"与框架之间的相对差距。
H2 2.5.252(内存库)
吞吐量(ops/s)
| 场景 | 原生 JDBC | huiche | MyBatis 3.5.19 | Hibernate 7.4 | jOOQ 3.21.9 | QueryDSL 5.1.0 | MyBatis-Flex 1.11.8 | MyBatis-Plus 3.5.18 | easy-query 3.3.1 | Jimmer 0.12.4 |
|---|---|---|---|---|---|---|---|---|---|---|
| 单条插入 | 296.2 k | 200.6 k | 213.0 k | 98.3 k | 66.3 k | 116.3 k | 105.9 k | 93.3 k | 154.6 k | 116.0 k |
| 批量插入 100 条 | 7.4 k | 5.4 k | 1.2 k | 1.8 k | 1.3 k | 1.9 k | 4.6 k | 1.4 k | 1.8 k | 3.3 k |
| 按主键查 1 条 | 538.6 k | 265.6 k | 157.9 k | 263.0 k | 119.8 k | 80.5 k | 147.6 k | 155.0 k | 184.2 k | 196.6 k |
| 条件查 100 行 | 165.3 k | 29.2 k | 17.6 k | 17.5 k | 27.6 k | 32.2 k | 10.5 k | 14.0 k | 63.4 k | 71.0 k |
| 按主键更新 1 条 | 158.9 k | 114.2 k | 127.2 k | 51.6 k | 73.8 k | 71.9 k | 77.7 k | 61.8 k | 81.5 k | 103.2 k |
| 按主键删除 1 条 | 284.5 k | 227.8 k | 225.5 k | 91.5 k | 128.3 k | 125.7 k | 165.9 k | 43.6 k | 154.0 k | 167.8 k |
相对原生 JDBC(×)
| 场景 | 原生 JDBC | huiche | MyBatis 3.5.19 | Hibernate 7.4 | jOOQ 3.21.9 | QueryDSL 5.1.0 | MyBatis-Flex 1.11.8 | MyBatis-Plus 3.5.18 | easy-query 3.3.1 | Jimmer 0.12.4 |
|---|---|---|---|---|---|---|---|---|---|---|
| 单条插入 | 1.00× | 0.68× | 0.72× | 0.33× | 0.22× | 0.39× | 0.36× | 0.32× | 0.52× | 0.39× |
| 批量插入 100 条 | 1.00× | 0.73× | 0.16× | 0.25× | 0.17× | 0.25× | 0.63× | 0.19× | 0.24× | 0.45× |
| 按主键查 1 条 | 1.00× | 0.49× | 0.29× | 0.49× | 0.22× | 0.15× | 0.27× | 0.29× | 0.34× | 0.36× |
| 条件查 100 行 | 1.00× | 0.18× | 0.11× | 0.11× | 0.17× | 0.20× | 0.06× | 0.08× | 0.38× | 0.43× |
| 按主键更新 1 条 | 1.00× | 0.72× | 0.80× | 0.32× | 0.46× | 0.45× | 0.49× | 0.39× | 0.51× | 0.65× |
| 按主键删除 1 条 | 1.00× | 0.80× | 0.79× | 0.32× | 0.45× | 0.44× | 0.58× | 0.15× | 0.54× | 0.59× |
PostgreSQL 17.7
吞吐量(ops/s)
| 场景 | 原生 JDBC | huiche | MyBatis 3.5.19 | Hibernate 7.4 | jOOQ 3.21.9 | QueryDSL 5.1.0 | MyBatis-Flex 1.11.8 | MyBatis-Plus 3.5.18 | easy-query 3.3.1 | Jimmer 0.12.4 |
|---|---|---|---|---|---|---|---|---|---|---|
| 单条插入 | 17.2 k | 13.1 k | 13.1 k | 6.9 k | 12.3 k | 13.3 k | 12.5 k | 12.2 k | 13.9 k | 12.0 k |
| 批量插入 100 条 | 2.2 k | 1.9 k | 782 | 132 | 223 | 1.0 k | 1.7 k | 492 | 152 | 633 |
| 按主键查 1 条 | 24.1 k | 16.4 k | 14.8 k | 16.1 k | 14.4 k | 13.9 k | 15.3 k | 14.6 k | 16.0 k | 15.5 k |
| 条件查 100 行 | 8.7 k | 6.0 k | 6.0 k | 5.2 k | 6.2 k | 7.0 k | 4.6 k | 5.3 k | 7.7 k | 7.7 k |
| 按主键更新 1 条 | 14.7 k | 13.1 k | 13.4 k | 7.5 k | 12.3 k | 11.4 k | 12.2 k | 10.5 k | 12.4 k | 12.9 k |
| 按主键删除 1 条 | 22.1 k | 18.4 k | 17.2 k | 8.8 k | 15.1 k | 15.1 k | 15.4 k | 12.1 k | 14.0 k | 15.9 k |
相对原生 JDBC(×)
| 场景 | 原生 JDBC | huiche | MyBatis 3.5.19 | Hibernate 7.4 | jOOQ 3.21.9 | QueryDSL 5.1.0 | MyBatis-Flex 1.11.8 | MyBatis-Plus 3.5.18 | easy-query 3.3.1 | Jimmer 0.12.4 |
|---|---|---|---|---|---|---|---|---|---|---|
| 单条插入 | 1.00× | 0.76× | 0.76× | 0.40× | 0.72× | 0.77× | 0.72× | 0.71× | 0.80× | 0.70× |
| 批量插入 100 条 | 1.00× | 0.89× | 0.36× | 0.06× | 0.10× | 0.48× | 0.77× | 0.23× | 0.07× | 0.29× |
| 按主键查 1 条 | 1.00× | 0.68× | 0.61× | 0.67× | 0.60× | 0.58× | 0.63× | 0.61× | 0.66× | 0.64× |
| 条件查 100 行 | 1.00× | 0.69× | 0.68× | 0.60× | 0.71× | 0.80× | 0.52× | 0.60× | 0.88× | 0.88× |
| 按主键更新 1 条 | 1.00× | 0.89× | 0.91× | 0.51× | 0.83× | 0.77× | 0.83× | 0.71× | 0.84× | 0.88× |
| 按主键删除 1 条 | 1.00× | 0.83× | 0.78× | 0.40× | 0.68× | 0.68× | 0.70× | 0.55× | 0.64× | 0.72× |
MySQL
吞吐量(ops/s)
| 场景 | 原生 JDBC | huiche | MyBatis 3.5.19 | Hibernate 7.4 | jOOQ 3.21.9 | QueryDSL 5.1.0 | MyBatis-Flex 1.11.8 | MyBatis-Plus 3.5.18 | easy-query 3.3.1 | Jimmer 0.12.4 |
|---|---|---|---|---|---|---|---|---|---|---|
| 单条插入 | 8.5 k | 7.8 k | 8.0 k | 2.8 k | 7.1 k | 8.0 k | 7.7 k | 7.2 k | 8.6 k | 6.7 k |
| 批量插入 100 条 | 737 | 645 | 335 | 77 | 83 | 71 | 613 | 92 | 82 | 77 |
| 按主键查 1 条 | 10.4 k | 9.9 k | 8.9 k | 9.3 k | 9.0 k | 7.8 k | 9.3 k | 8.9 k | 9.3 k | 8.3 k |
| 条件查 100 行 | 4.3 k | 4.0 k | 3.3 k | 3.4 k | 3.7 k | 3.6 k | 3.0 k | 2.9 k | 4.3 k | 4.0 k |
| 按主键更新 1 条 | 8.6 k | 8.3 k | 7.3 k | 3.4 k | 7.0 k | 7.2 k | 7.9 k | 7.5 k | 8.2 k | 7.5 k |
| 按主键删除 1 条 | 10.8 k | 10.0 k | 10.6 k | 3.9 k | 10.3 k | 9.8 k | 10.0 k | 8.6 k | 9.9 k | 10.0 k |
相对原生 JDBC(×)
| 场景 | 原生 JDBC | huiche | MyBatis 3.5.19 | Hibernate 7.4 | jOOQ 3.21.9 | QueryDSL 5.1.0 | MyBatis-Flex 1.11.8 | MyBatis-Plus 3.5.18 | easy-query 3.3.1 | Jimmer 0.12.4 |
|---|---|---|---|---|---|---|---|---|---|---|
| 单条插入 | 1.00× | 0.92× | 0.94× | 0.33× | 0.83× | 0.94× | 0.90× | 0.85× | 1.01× | 0.79× |
| 批量插入 100 条 | 1.00× | 0.88× | 0.45× | 0.10× | 0.11× | 0.10× | 0.83× | 0.12× | 0.11× | 0.11× |
| 按主键查 1 条 | 1.00× | 0.96× | 0.86× | 0.89× | 0.86× | 0.76× | 0.90× | 0.86× | 0.90× | 0.80× |
| 条件查 100 行 | 1.00× | 0.91× | 0.76× | 0.79× | 0.85× | 0.83× | 0.69× | 0.68× | 0.98× | 0.93× |
| 按主键更新 1 条 | 1.00× | 0.97× | 0.85× | 0.39× | 0.81× | 0.84× | 0.92× | 0.88× | 0.95× | 0.87× |
| 按主键删除 1 条 | 1.00× | 0.92× | 0.97× | 0.36× | 0.94× | 0.90× | 0.92× | 0.79× | 0.91× | 0.92× |
结论要点
huiche 的优势
- 最接近裸 JDBC 的整体表现:MySQL 环境下六项全部维持在 0.88×–0.97×,是本次对比中距原生 JDBC 上限最近的一档。
- 批量插入优势明显:H2 下达原生 JDBC 的 0.73×,领先第二名的 MyBatis-Flex(0.63×);PostgreSQL 下 0.89×,是唯一的 0.8× 以上;MySQL 下 0.88× 同样居前。相比之下多数 ORM 在批量场景普遍只有 0.1×–0.3×。
- 主键点查:H2 下与 Hibernate 并列最快(0.49×),PostgreSQL 下是全场最快(0.68×)。
- 写操作接近 JDBC:更新/删除在 MySQL 下分别达到 0.97×、0.92×。
需要如实说明的差距
- 单条插入:H2 下 MyBatis(0.72×)略高于 huiche(0.68×);MySQL 下 easy-query(1.01×)最高,huiche 0.92×。
- 条件查多行:这是 huiche 相对偏弱的一项。H2 下 huiche 为 0.18×,低于 QueryDSL(0.20×)、easy-query(0.38×)、Jimmer(0.43×);PostgreSQL 下 easy-query 与 Jimmer(0.88×)也高于 huiche(0.69×)。
条件查多行偏慢可以自己绕过
自 4.0.6 起 RowMapper 已取消密封,业务可自行实现行映射。若某类查询对映射开销特别敏感, 可以实现一个针对该结果集的自定义 RowMapper(按列下标读取),通过 executor.sql(...).query(new MyRowMapper()) 使用。详见 AI 助手使用指南 - 自定义查询。
复现方式
基准工程位于独立仓库 huiche-benchmark(与主项目平级),使用 JMH,支持三种数据库环境切换:
bash
# H2 内存库(默认)
mvn clean package
java -jar target/benchmarks.jar
# 本地 PostgreSQL / MySQL
mvn clean package -Dbench.db=pg
mvn clean package -Dbench.db=mysql
# 连接参数可配置:默认指向本机测试实例,可用下列系统属性覆盖(MySQL 对应 bench.mysql.*)
# -Dbench.pg.host=主机 -Dbench.pg.port=端口 -Dbench.pg.db=库名 -Dbench.pg.user=用户 -Dbench.pg.password=密码该工程以 <parent>huiche</parent> 继承主项目,依赖版本由 ${revision} 钉死, 构建前需先对主项目执行 mvn install 使对应版本进入本地仓库。