JPAで次のSQLクエリを作成しようとして立ち往生しています(JavaとJPAはまだ新しいので、かなり検索しましたが、まだ取得できません。初心者の質問の場合は申し訳ありません)。
私が望んでいることをほぼ実行し、機能するJPQLクエリ
SELECT s
FROM Sentence s
INNER JOIN s.words sw
WHERE s.date = :date
AND sw IN (:words)
SentenceとWordはどちらもクラスですSentenceWordは、SentenceとWordの間のManyToMany結合です。つまり、s.wordsはセンテンスに属するリストです。s.Dateは、スタッフデータを格納するImportオブジェクトです。import:dateは、照合する単一のImportです。:wordsは、文中でチェックしたい単語のリストです。
このクエリは、IN演算子に対しては問題なく機能します。
ただし、現在、センテンスに、渡すリスト内のすべての単語が含まれているかどうかを確認する必要があります(s.wordsリストからアセンブルします)。
現在、文字列ビルダーとFOREACHループを使用してWHEREAND句を手動で作成し、それらを文字列に追加してクエリを使用しています。それは動作しますが、それは非常に醜く、一見反Javayであり、私はそれを正しい/タイプセーフな方法でやりたいと思っています。
CriteriaBuilderとCriteriaQueryを見つけましたが、INNERJOINを機能させることができませんでした。まったく。そして悲しいことに、それは私がRTFMした後です。http://docs.jboss.org/hibernate/orm/4.0/hem/en-US/html/querycriteria.html#querycriteria-from-join
動的なWHEREANDクエリの場合、これは私が得た限りです
q.where(
cb.and(
cb.equal(s.get("date"), date)
for (Word word : words) {
, cd.equal(s.get("words"), word)
}
)
);
しかし、それはすべて間違っているように思われ、参加できないため、テストできません。誰かが私を単純な人々の結合とコレクションをループしてAND句を作成するためのCriteriaQueryチュートリアルの正しい方向に向けることができれば、またはこの例で正しいクエリを書き出すことができれば、私は非常にありがたいです!
更新-クエリの効率
代替のJPQLクエリは次のようになります。
SELECT s
FROM Sentence s
INNER JOIN s.words sw
WHERE s.date = :date
AND sw IN (:words)
GROUP BY s
HAVING count(sw) = :numberOfWords
Group ByはJQPLで必要とされているようですが、SQLの同じクエリでは必要ありません。私は今小さなデータセットを持っているので、両方とも非常に高速ですが、一方が他方よりも優先されるかどうか興味があります。
また、クエリを使用してパラメータを設定していますが、これらに使用するより良いクラスはありますか?名前付きの用語の方が?よりも好きです。
Query query = JPA.em().createQuery(jpql);
query.setParameter("date", date);
query.setParameter("numberOfWords", new Long(words.size()));
query.setParameter("words", words);