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

man*_*nta 31 java performance spring-jdbc querydsl jooq

有人能指出一些关于可用于Java的不同Query DSL库之间性能比较的资源,如:Querydsl,jOOQ,JEQUEL,activejdbc,iciql等等......

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

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

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

用jOOQ,iciql,QueryDSL更新我的经验:

虽然我错过了在我的原帖中提到这一点,但我也热衷于易用性和我在实体类中需要的开销(如果需要任何额外的注释或实现).

jOOQ:

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

Iciql:

  • 实体可以映射到没有或很少的变化(可以使用总共3种方式映射)
  • 但由此限制只选择查询(更新/删除/ ...再次要求实体更改)

QueryDSL:

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

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

综上所述,我坚持编写命名查询:(但由于Lukas Eder的答案似乎解释了我原来的帖子关注(表现),我接受了他的.

Luk*_*der 28

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

与此相比,字符串连接实在是可以忽略不计,甚至对复杂的SQL构造几个UNIONs,嵌套SELECTs,JOINs,semi-JOINs,anti-JOINs,等,所以我猜你提到类似的方式进行,因为它们让你保持控制权框架你的SQL.

另一方面,这些框架中的一些框架或使用模式实际上可能将整个结果集提取到内存中.可因为Java的泛型,最原始的类型(造成的问题,如果您的结果集都很大,也是int,long等)很可能映射到其相应的包装(Integer,Long).

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

至于iciql,这是一个叉JaQu,有可能是由他们使用Java的仪器进行反编译的事实一些额外的影响自然的语法.但我想这可以省略,如果它意味着太大的影响.

  • Querydsl通过迭代支持eager和lazy抓取.Querydsl支持结果集中的基本类型. (4认同)
  • 我同意Lukas,Querydsl也为大多数查询使用单个StringBuilder,并且String构建开销很小.创建中间DSL对象和相关垃圾收集所产生的开销很难正确测量. (3认同)
  • @mrCoder:是的,两个框架也用于*执行*查询,即使该步骤是可选的 - 如果您希望将它们用作普通查询构建器.据我所知,JEQUEL并非如此.在jOOQ中,可以使用[Query#getSQL()](http://jooq.sourceforge.net/javadoc/latest/org/jooq/Query.html#getSQL%28%29)获取SQL.当然,Timo会在一分钟内告诉您如何使用QueryDSL完成此操作... (2认同)

Ada*_*ent 6

您还应该查看MyBatis Statement Builder.

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