2012-10-07 33 views
0

我被困在JPA中(在Java和JPA中仍然是新的,我搜索了很多東西,仍然沒有得到它,抱歉if這是一個noob問題)。JPQL標準查詢播放框架1x內部聯接和where子句結構

JPQL查詢做幾乎我想要的東西,作品

SELECT s 
FROM Sentence s 
INNER JOIN s.words sw 
WHERE s.date = :date 
AND sw IN (:words) 

句子和詞都是類 SentenceWord是一個多對多句子和詞之間的連接。 所以s.words是屬於句子的列表。 s.Date是一個導入對象,用於存儲導入的東西數據 :日期是我們希望匹配的單個導入。 :單詞是我們想要在句子中檢查的單詞的列表。

此查詢適用於IN運算符。

但是,我們現在有檢查一個句子是否包含我們傳遞的列表中的所有單詞的需求(即我們從s.words列表中組裝)。

現在我只是手動構建WHERE AND子句使用字符串生成器和FOR EACH循環並將它們附加到字符串和使用查詢。它的作品,但它超級醜陋,看似反Javay,我想這樣做正確/類型安全的方式。

我發現CriteriaBuilder和CriteriaQuery,但一直沒有能夠讓INNER JOIN工作。完全一樣。可悲的是,這是在我RTFM之後。 http://docs.jboss.org/hibernate/orm/4.0/hem/en-US/html/querycriteria.html#querycriteria-from-join

對於動態WHERE和查詢,這是據我已經得到了

q.where(
    cb.and(
     cb.equal(s.get("date"), date) 

     for (Word word : words) { 
      , cd.equal(s.get("words"), word)   
     } 

    ) 
); 

但是,這只是似乎都錯了,我不能測試它,因爲我不能做的加入。如果有人能指出我正確的方向,爲簡單的人加入CriteriaQuery教程,並通過集合循環來創建AND子句,或者在這個例子中寫出正確的查詢,我將非常感謝!

更新 - 查詢效率

替代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 

集團通過似乎是要求JQPL而不是在SQL相同的查詢。我現在只有一個小數據集,所以兩者都很快,但如果一個人比另一個人更喜歡,那麼我很好奇。

此外,我只是使用查詢來設置參數,是否有更好的類用於這些?我喜歡有名的術語比?更好。

Query query = JPA.em().createQuery(jpql); 
query.setParameter("date", date); 
query.setParameter("numberOfWords", new Long(words.size())); 
query.setParameter("words", words); 

回答

0

以下查詢應該做你想做的。不知道如果有一個更好的選擇:

select s 
from Sentence s 
where s.date = :date 
and :numberOfWords = (select count(sw) from SentenceWord sw 
         where sw.sentence = s 
         and sw in (:words)) 

其中numberOfWords是包含進言相匹配的集合字的數目。 當然,這個集合不能包含任何重複。

解釋查詢的作用:它檢查要匹配的單詞集合中的單詞數量是否等於該集合中單詞部分的數量並且由該句子引用。

+0

我還沒有在Java中測試過,會很快做到,但是這個SQL會得到想要的結果。你知道這個使用子查詢的查詢比使用'GROUP BY s'和'HAVING count()=:numberOfWord' – bladmiral

+0

更有效嗎?我沒有看到'group by'如何被使用。 –

+0

請參閱使用group by的查詢的原始問題中的更新部分。你的查詢和那個查詢都會產生相同的SQL結果。 JPQL不允許這樣的事情嗎? – bladmiral

0

您可以使用JpqlSelect中發揮與和平等的

JpqlSelect select = new JpqlSelect(); 
Map<String, Object> params = new HashMap<String, Object>(); 
select.select("s"); 
select.from("Sentence s inner join s.words sw"); 
select.where("where s.date = ?"); 
params.param(date); 
for (Word word : words) { 
    select.andWhere("sw = ?"); 
} 
return fin(select.toString(), select.getParams()); 

dinamically構建查詢,但我不認爲這查詢你想用一個句子的所有單詞的一個不等於每個單詞在你的單詞參數中。我認爲JB的查詢更好

+0

我也認爲JB一個更適合這個問題,但非常感謝您的回答,因爲我不知道Play框架中用於構建動態查詢的JpqlSelect幫助程序方法!這個方法看起來很有用,我想我會在很多地方使用它。 – bladmiral