32

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

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

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

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

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

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

约克:

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

爱奇艺:

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

查询DSL:

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

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

综上所述,我坚持编写命名查询:(但正如 Lukas Eder 的回答似乎解释了我最初关注的帖子(性能),我接受了他的。

4

4 回答 4

29

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

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

另一方面,这些框架中的某些框架或使用模式实际上可能会将整个结果集提取到内存中。如果您的结果集很大,这可能会导致问题,还因为使用 Java 的泛型,大多数原始类型(int,long等)可能映射到它们相应的包装器(Integer, Long)。

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

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

于 2011-08-31T08:30:39.143 回答
6

你也应该看看MyBatis Statement Builder

虽然 MyBatis 显然是一种映射技术,但它确实有一个似乎与 MyBatis 分离的 Statement builder DSL(也就是说,您不需要 MyBatis 的任何其他东西来使用构建器......令人讨厌的是它不在自己的 jar 中)。我不喜欢它,因为它使用 ThreadLocals。

于 2012-05-01T18:25:02.503 回答
2

我不能代表其他框架,但我对性能进行了原始分析以比较ActiveJDBC和 Hibernate。测试是在具有 8G RAM、SSD 驱动器的笔记本电脑上针对 MySQL 进行的。带有几个简单列和代理 ID PK 的表 PEOPLE。

一项测试是将 50K 记录作为对象插入,另一项测试是一次从表中读取 50K 对象(在内存中)。在这两项测试中,ActiveJDBC 都显示出比 Hibernate 提高 40% 的性能。在任何一种情况下,生成的查询都是简单的插入和选择,彼此非常相似。

希望这可以帮助,

伊戈尔

于 2011-09-01T22:44:02.703 回答
1

用于编程 SQL 查询创建的轻量级、无依赖库是OpenHMS SQL Builder库:

https://openhms.sourceforge.io/sqlbuilder/

可作为 Maven 依赖项使用:

https://mvnrepository.com/artifact/com.healthmarketscience.sqlbuilder/sqlbuilder

于 2019-01-31T16:14:06.803 回答