比较 Querydsl、jOOQ、JEQUEL、activejdbc、iciql 和其他查询 DSL

2022-09-01 09:55:54

有人可以给我指出一些关于可用于Java的不同Query DSL库之间的性能比较的资源,例如:QuerydsljOOQJEQUELactivejdbciciql等...

背景:我使用的是Spring JDBC模板,但这仍然需要以纯字符串格式编写查询。虽然我在编写直接查询时没有问题,但我担心直接依赖于数据库表名称。我不想使用任何ORM框架,如Hibernate或JPA / EclipseLink。我需要尽可能高的原始性能(IMO,它们适用于更多以CRUD为中心的应用程序)。只有当这些DSL有一点点时,我才能负担得起一些轻微的开销(我相信,它主要是StringBuilder/String串联!

我考虑过使用在一些xml中外部化的命名查询。但只是尝试评估不同的查询 DSL 库提供的值。

编辑:更多关于我的要求:我想知道在使用其 API 方法构建中等复杂查询时,它们之间的性能比较。我所需要的只是使用这些查询DSL库中的任何一个生成一个查询字符串,并将其传递给Spring JDBC模板。因此,我想知道添加此中间步骤是否会造成相当大的性能损失,我想使用命名查询或构建自己的库,该库仅使用StingBuilder或类似方法

更新我对jOOQ,iciql,QueryDSL的体验:

尽管我没有在原始帖子中提到这一点,但我也热衷于易用性和实体类中需要的开销(例如是否需要任何其他注释或实现)。

jOOQ:

  • 需要以特定方式将实体属性更改为库
  • 可以返回 SQL 查询字符串

Iciql:

  • 实体可以在没有或几乎没有变化的情况下进行映射(可以使用总共3种方式进行映射)
  • 但它仅限于选择查询(用于更新/删除/...需要再次更改实体)

QueryDSL:

  • 将实体与表绑定的多种方式(除了特定于库的方式,还支持使用 JPA 注释)。但我们至少需要修改实体
  • 没有简单/直接的方法来获取查询字符串

(所有观察结果都很少,我对此知之甚少;如果其中任何一个不正确,请更正)

综上所述,我坚持编写命名查询:(但是,由于卢卡斯·埃德尔(Lukas Eder)的答案似乎解释了我最初的帖子关注点(性能),我已经接受了他。


答案 1

在现代JVM中,您不应该过于担心SQL字符串串联。任何数据库抽象层可能产生的真正开销(与到数据库和返回的往返时间相对较高相比)通常是由于二级缓存,这是在Hibernate/JPA中完成的。或者,通过将对象模型映射到 SQL 的效率低下,从而无法使用索引或常规查询转换。

与此相比,字符串串联确实可以忽略不计,即使对于具有多个,嵌套,,,等的复杂SQL构造也是如此,因此我猜您提到的所有框架都以类似的方式执行,因为它们允许您保持对SQL的控制。UNIONsSELECTsJOINssemi-JOINsanti-JOINs

另一方面,这些框架中的某些框架或使用模式实际上可能会将整个结果集提取到内存中。如果结果集很大,这可能会导致问题,也因为对于Java的泛型,大多数基元类型(,等)可能映射到其相应的包装器(,)。intlongIntegerLong

至于 jOOQ(我是其中的开发人员),我之前已经使用 YourKit Profiler 分析了该库,以便执行大量查询。批量工作始终在数据库中完成,而不是在查询构造中完成。jOOQ 对每个查询使用一个单一的查询。我想(未经验证),QueryDSLJEQUEL做同样的事情......StringBuilder

至于 iciql,它是 JaQu 的一个分支,由于它们使用 Java 工具来反编译其自然语法,可能会有一些额外的影响。但我想这可以省略,如果它意味着太大的影响。


答案 2

您还应该查看 MyBatis 语句生成器

虽然MyBatis显然是一种映射技术,但它确实有一个语句生成器DSL,它似乎与MyBatis分离(也就是说,你不需要MyBatis的任何其他东西来使用生成器......令人讨厌的是,它不在自己的罐子里)。我不喜欢它,因为它使用ThreadLocals。


推荐