web-dev-qa-db-ja.com

Querydsl、jOOQ、JEQUEL、activejdbc、iciql、およびその他のクエリDSLの比較

QuerydsljOOQ[〜#〜] jequel [〜#〜]activejdbc、- iciqlなど...

背景:Spring JDBCテンプレートを使用していますが、それでもクエリをプレーンな文字列形式で記述する必要がありました。直接クエリの記述には問題はありませんが、DBテーブル名に直接依存していることが心配です。 HibernateやJPA/EclipseLinkなどのORMフレームワークを使用したくありません。できるだけ高い生のパフォーマンスが必要です(IMO、よりCRUD中心のアプリケーションに適しています)。これらのDSLに少しオーバーヘッドがある場合は、それが少しの場合に限ります(おそらく、ほとんどがStringBuilder/String連結です!)

一部のxmlで外部化された名前付きクエリの使用を検討しました。しかし、さまざまなクエリDSLライブラリが提供する価値を評価しようとするだけです。

編集:要件の詳細: APIメソッドを使用して中程度に複雑なクエリを作成するときのパフォーマンスの比較を知りたい。私が必要なのは、これらのクエリDSLライブラリのいずれかを使用してクエリ文字列を生成し、それをSpring JDBCテンプレートに渡すことだけです。したがって、この中間ステップを追加するとパフォーマンスが大幅に低下するかどうかを知りたいので、名前付きクエリを使用するか、StingBuilderまたは同様のアプローチを使用する独自のライブラリを構築します

update jOOQ、iciql、QueryDSLでの私の経験:

元の投稿でこれについて言及し忘れていましたが、エンティティクラスで必要な使いやすさとオーバーヘッド(追加の注釈や実装が必要な場合など)にも熱心です。

jOOQ:

  • エンティティのプロパティをライブラリ固有の方法に変更する必要があります
  • sQLクエリ文字列を返すことができます

イシクル:

  • エンティティは変更なしで、またはほとんど変更せずにマッピングできます(合計3つの方法を使用してマッピングできます)
  • ただし、選択したクエリのみに制限されます(更新/削除/ ...には、エンティティの変更が再度必要です)。

QueryDSL:

  • エンティティをテーブルにバインドする複数の方法(ライブラリ固有の方法以外で、JPAアノテーションの使用がサポートされています)。しかし、少なくともエンティティを変更する必要があります
  • クエリ文字列を取得する単純な/直接的な方法はありません

(すべての観察はこれらについて私がほとんど知識を持っていません。これらのいずれかが正しくない場合は修正してください)

上記のすべてについて、私は名前付きクエリを書くことに固執しています:(しかし、Lukas Ederの回答が私の元の投稿の懸念(パフォーマンス)について説明しているように見えるので、彼を受け入れました。

31
manikanta

最近のJVMでは、SQL文字列の連結についてあまり気にする必要はありません。データベースアブストラクションレイヤーが生成する可能性のある真のオーバーヘッド(データベースへの往復時間が比較的長い場合と比較して)は、通常、Hibernate/JPAで行われる2次レベルのキャッシュが原因です。または、インデックスまたは一般的なクエリ変換の使用が不可能になるような方法で、オブジェクトモデルを非効率的にSQLにマッピングします。

それと比較すると、いくつかのUNIONs、ネストされたSELECTsJOINssemi-JOINsanti-JOINsを含む複雑なSQL構文の場合でも、文字列の連結はごくわずかです。 、など、SQLの制御を維持できるので、あなたが言及したすべてのフレームワークが同様の方法で実行されると思います。

一方、一部のフレームワークまたはそれらのフレームワークの使用モードでは、実際に結果セット全体がメモリにフェッチされる場合があります。結果セットが大きい場合、問題が発生する可能性があります。また、Javaのジェネリックでは、ほとんどのプリミティブ型(intlongなど)が対応するラッパー(IntegerLong)。

jOOQ (そのうち私は開発者です)については、以前に YourKit Profiler を使用してライブラリをプロファイルし、大量のクエリを実行しました。一括処理は、クエリの構築ではなく、常にデータベースで行われました。 jOOQはすべてのクエリに対して単一のStringBuilderを使用します。 QueryDSL[〜#〜] jequel [〜#〜] が同じことをする(検証されていない)と思います...

iciqlJaQ の分岐ですが、Java逆コンパイルするためのインストルメンテーションを使用しているため、さらに影響がある可能性があります 自然な構文 。しかし、影響が大きすぎる場合は省略できると思います。

28
Lukas Eder

MyBatis Statement Builderも参照してください。

MyBatisは明らかにマッピングテクノロジーですが、MyBatisから切り離されているように見えるステートメントビルダーDSLがあります(つまり、ビルダーを使用するためにMyBatisから他に何も必要ありません...厄介なことに、独自のjarにはありません)。 ThreadLocalsを使用しているため、気に入らない。

6
Adam Gent

他のフレームワークについて話すことはできませんが、 ActiveJDBC とHibernateを比較するために、パフォーマンスの基本的な分析を行いました。テストは、8G RAM、MySQLに対するSSDドライブを搭載したラップトップで行われました。いくつかの単純な列とサロゲートID PKを持つテーブルPEOPLE。

1つのテストは50Kレコードをオブジェクトとして挿入することであり、もう1つは50Kオブジェクトをテーブルから一度に(メモリ内で)読み取ることでした。どちらのテストでも、ActiveJDBCはHibernateよりもパフォーマンスが40%向上しました。どちらの場合でも、生成されたクエリは単純な挿入と選択で、互いによく似ていました。

お役に立てれば、

イゴール

2
ipolevoy

プログラムによるSQLクエリ作成のための軽量で依存性のないライブラリは、OpenHMS SQL Builderライブラリです。

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

Maven依存関係として利用可能:

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

1
lars