Java JPQL条件查询播放框架1x内部联接和Where子句构造

Java JPQL条件查询播放框架1x内部联接和Where子句构造,java,playframework,jpql,playframework-1.x,criteriaquery,Java,Playframework,Jpql,Playframework 1.x,Criteriaquery,我一直在尝试用JPA构建下面的SQL查询(对Java和JPA来说仍然是新的,我搜索了很多,但仍然没有得到它,如果这是一个noob问题,很抱歉) JPQL查询,它几乎实现了我想要的功能,并且可以正常工作 SELECT s FROM Sentence s INNER JOIN s.words sw WHERE s.date = :date AND sw IN (:words) 句子和单词都是类 句子词是句子和词之间的多个连接词。 所以s.words是一个属于句子的列表。 s、 Date是一个导入对

我一直在尝试用JPA构建下面的SQL查询(对Java和JPA来说仍然是新的,我搜索了很多,但仍然没有得到它,如果这是一个noob问题,很抱歉)

JPQL查询,它几乎实现了我想要的功能,并且可以正常工作

SELECT s
FROM Sentence s
INNER JOIN s.words sw
WHERE s.date = :date
AND sw IN (:words)
句子和单词都是类 句子词是句子和词之间的多个连接词。 所以s.words是一个属于句子的列表。 s、 Date是一个导入对象,用于存储导入时的填充数据 :date是我们要匹配的单个导入。 :单词是我们要在句子中检查的单词的列表

这个查询对于IN操作符来说效果很好

然而,我们现在需要检查一个句子是否包含我们正在传递的列表中的所有单词(我们从s.words列表中收集)

现在我只是使用字符串生成器和FOR-EACH循环手动构建WHERE和子句,并将它们附加到字符串和using查询中。它可以工作,但它非常丑陋,看起来像是反Javay的,我想用正确的/类型安全的方式来做

我找到了CriteriaBuilder和CriteriaQuery,但就是无法让内部连接正常工作。完全可悲的是,这是在我RTFM之后

对于动态WHERE和query,这是我所能得到的

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
JQPL似乎需要GROUPBY,但SQL中的同一查询不需要GROUPBY。我现在只有一个小数据集,所以两个都很快,但我很好奇,一个比另一个好

另外,我只是使用Query来设置参数,是否有更好的类用于这些参数?比起?我更喜欢命名术语

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

下面的查询应该执行您想要的操作。不知道是否有更好的选择:

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
是包含在要匹配的单词集合中的单词数。 当然,此集合不能包含任何副本


解释查询的作用:它检查要匹配的单词集合中的单词数是否与该集合中的单词数部分相等,并由句子引用。

您可以使用JpqlSelect在游戏中使用and和equal以友好方式构建查询

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());
JpqlSelect=newjpqlselect();
Map params=新的HashMap();
选择。选择;
选自(“句子的内部连接s.words sw”);
选择.where(“其中s.date=?”);
参数参数(日期);
for(单词:单词){
选择.andWhere(“sw=?”);
}
返回fin(select.toString(),select.getParams());

但是我不认为这个查询是你想要使用的,一个句子的所有单词都不等于你单词参数中的每个单词。我认为JB的查询更好

我还没有用Java测试过,很快就会测试出来,但是这个SQL得到了期望的结果。您知道使用子查询的此查询是否比使用“分组依据s”和“HAVING count()=:numberOfWord”更有效。我不知道如何使用
分组依据。有关使用分组依据的查询,请参阅原始问题中的更新部分。您的查询和那个查询都会生成相同的SQL结果。JPQL不允许这样的事情吗?我也认为对于这个特定的问题,JB方法更好,但也非常感谢您的回答,因为我不知道在Play框架中用于构建动态查询的JpqlSelect helper方法!这种方法看起来非常有用,我想我会在未来的很多地方使用它。