この回答で説明されているように、基準には JPQL または生の SQL を使用するよりもいくつかの利点があります。リファクタリングの親しみやすさ; 文字列への依存が少なくなります (ただし、まだいくつかあります)。そして、非常に大きな欠点が 1 つあります。それは、読みにくく、単純に醜いことです。タイプセーフで読み取り可能なリレーショナル データベースにアクセスするための (JPA 以外の) Java API はありますか?
4 に答える
Timo WestkämperはQueryDSLで良い仕事をしました。このライブラリは、さまざまな永続化プロバイダー (JPA、MongoDB、Lucene...) をクエリするための DSL を提供します。
しかし、私は多くの場合、最も一般的なクエリ (フィールドの一部を制限するエンティティをリストする) を簡素化する手作りのソリューションを使用しており、常に同じ行を書くことができませんでした。ほとんどの複雑なクエリについては、判読不能で冗長な Criteria API に切り替えました。
MyBatis は、カスタム SQL、ストアド プロシージャ、および高度なマッピングをサポートするファースト クラスの永続化フレームワークです。MyBatis では、ほとんどすべての JDBC コードと、パラメータの手動設定と結果の取得が不要になります。MyBatis は、単純な XML またはアノテーションを構成に使用して、プリミティブ、マップ インターフェイス、Java POJO (Plain Old Java Objects) をデータベース レコードにマップできます。
または、nobeh が提案したように: jOOQ。
次のユーティリティクラスに直面して、JPA検索をより簡単にする「究極の」ソリューションを見つけました: DynamicQueryBuilder
メタモデルを与えるので、結合を使ってリレーションを記述する必要はありません。
テンプレート pojo で検索 !!! 値をエンティティ インスタンスに入れるだけで、条件として使用されます。
ビルダー パターンを使用しているため、非常に読みやすいです。
Bank bank = new Bank(); bank.setId(12L); bank.setAchCode("1213"); bank.setCbeCode("1234"); bank.setStatus(new Lookups(1L)); bank.setAchShortName("121"); List<integer> ids = new ArrayList<integer>(); ids.add(1); ids.add(2); ids.add(3); ids.add(4); ids.add(5); List<string> cbeCodes = new ArrayList<string>(); cbeCodes.add("1111"); cbeCodes.add("2222"); DynamicQueryBuilder queryDyncBuilder1 = new DynamicQueryBuilder.Builder(null).select(bank).withOperType(Operator.OperType.AND). withAdvancedParam("cbeCode", LIKE, PERCENT_AROUND).withAdvancedParam("id", IN, ids) .withAdvancedParam("achCode", BETWEEN, cbeCodes).withAdvancedParam("achShortName", GT) .orderBy("id").orderBy("cbeCode", true).orderBy("status.code", true).build(); System.out.println(queryDyncBuilder1.getQueryString());
上記の呼び出しを実行すると、コンポーネントは次の結果の JPQL クエリを構築します。
SELECT b
FROM Bank b
WHERE b.status = :status
AND b.cbeCode LIKE :cbeCode
AND b.achShortName > :achShortName
AND b.id IN :id
AND (b.achCode BETWEEN :achCodeFrom AND :achCodeTo)
ORDER BY b.status.code DESC, b.id ASC, b.cbeCode DESC