简体   繁体   English

如何在 SELECT 之间使用“IN”编写“JPQL”查询?

[英]How to write "JPQL" query with "IN" between SELECTs?

I wrote this JPQL query and expect a result as List<Question> :我编写了这个JPQL查询并期望得到List<Question>的结果:

@Query("SELECT q FROM Question q WHERE q.id IN (SELECT qc.questions FROM QCard qc WHERE qc.id IN (SELECT ct.qCards FROM CTest ct WHERE ct.id=:id))")

These are my classes:这些是我的课:

class CTest {
  id List<QCard>
}

class QCard{
  id List<Question>
}

class Question{
  id
}

I expected all questions as return for given CTest.id .我希望所有问题都作为给定CTest.id的回报。 But I got a compiler-error with message:但是我收到了一个带有消息的编译器错误:

SQLSyntaxErrorException SQLSyntaxErrorException

I tried use ":" before "select" words but it had not helped.我尝试在“选择”单词之前使用“:”,但没有帮助。

What is wrong?怎么了?

List<Question> findByIdIn(List<Long> idList); //In repository

or或者

String qlString = "select i from Item i where i.name IN :names"; 
Query q = em.createQuery(qlString, Item.class);
List<String> names = Arrays.asList("foo", "bar");
q.setParameter("names", names);
List<Item> actual = q.getResultList();

I did those example in my past work, check it, tnx我在过去的工作中做了这些例子,检查一下,tnx

In your existing query, in inner queries you are selecting entities and checking IN against Id, which will definitely won't work.在您现有的查询中,在内部查询中,您正在选择实体并根据 Id 检查 IN,这肯定是行不通的。 As you can't complete entry with the Id.因为您无法使用 ID 完成输入。

As you haven't shared your complete entity structure, assuming that you have two way relationship declared correctly in entities, here I am placing a reference query which uses the join:由于您尚未共享完整的实体结构,假设您在实体中正确声明了两种方式的关系,这里我放置了一个使用连接的参考查询:

@Query("SELECT q FROM Question q JOIN q.qCard qc WHERE q.qCardId = qc.id AND qc.cTestId = :id")

Where qCardId is the foreign key reference of QCard entity in Question entity and cTestId is the foreign key reference of CTest entity in QCard entity.其中qCardIdQuestion实体中QCard实体的外键引用, cTestIdQCard实体中CTest实体的外键引用。

You can use this for your reference to update your query with joins.您可以使用它作为参考来使用连接更新您的查询。

Test your SQL query in an SQL-client (eg Squirrel, DbVisualizer, etc.).在 SQL 客户端(例如 Squirrel、DbVisualizer 等)中测试您的 SQL 查询。

Assuming your foreign key s are named:假设您的外键命名为:

  • question_id in table QCardQCard中的question_id
  • card_id in table CTestCTest中的card_id

you could have an SQL with subselects like:你可以有一个 SQL 子选择,如:

SELECT q.id
FROM Question q 
WHERE q.id IN (
  SELECT qc.question_id
  FROM QCard qc
  WHERE qc.id IN (
    SELECT ct.card_id
    FROM CTest ct
    WHERE ct.id = 1  -- example test id
  )
)

Does it return the expected result or are there syntax errors?它是返回预期结果还是存在语法错误?

Then subsequently replace your subselects by JOIN s.然后随后用JOIN替换您的子选择

  1. Question and Cards问题和卡片
SELECT q.id, c.id
FROM Question q 
JOIN QCard c ON c.question_id = q.id
  1. Cards and Tests卡片和测试
SELECT c.id, t.id
FROM QCard c 
JOIN CTest t ON t.card_id = c.id
  1. All together全部一起
SELECT q.id, c.id, t.id
FROM Question q 
JOIN QCard c ON c.question_id = q.id
JOIN CTest t ON t.card_id = c.id

Note: add WHERE clauses like WHERE t.id = 1 if needed.注意:如果需要,添加WHERE子句,如WHERE t.id = 1

Experiment with the FROM/JOIN order as it makes sense.尝试 FROM/JOIN 顺序,因为它是有意义的。

Then translate the running SQL query to JPQL.然后将正在运行的 SQL 查询转换为 JPQL。 For example:例如:

@Query("SELECT q"
+ " FROM CTest test" 
// a test has many cards (1:n)
+ " JOIN QCard card ON card.id = test.card_id"  // associated cards
// a card has many questions (1:n)
+ " JOIN Question q ON q.id = card.question_id"  // associated questions
+ " WHERE test.id = :id")
public List<Question> findQuestionsByTestId(String id);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM