Table1、table2という名前の2つのテーブルがあります。両方のテーブルに同じフィールド数があります。これら2つのテーブルの間に関係はありません。私の要件は、table2にないtable1のすべてのレコードが必要です。そこで、CriteriaAPIを使用してクエリを作成しました。しかし、それは正しい結果を与えていません。私はこのJPAとcriteriaAPIを初めて使用するので、どこで間違っているのかを指摘できます。これを行うために使用している以下のコード。
CriteriaBuilder cb = mediationEntityManager.getCriteriaBuilder();
CriteriaQuery<Table1> cq = cb.createQuery(Table1.class);
Root<Table1> table1 = cq.from(Table1.class);
cq.select(table1)
Subquery<Table2> subquery = cq.subquery(Table2.class)
Root table2 = subquery.from(Table2.class)
subquery.select(table2)
cq.where(cb.not(cb.exists(subquery)))
TypedQuery<Table1> typedQuery = mediationEntityManager.createQuery(cq);
List<Table1> resultList = typedQuery.getResultList();
MySQLクエリ:
SELECT table1
FROM table1 table1
WHERE NOT EXISTS (SELECT table2
FROM table2 table2
WHERE table2.name = table1.name
AND table2.education = table1.education
AND table2.age = table1.age)
AND table1.name = 'san'
AND table1.age = '10';
上記のMySQLクエリのJPA基準APIクエリが必要です。
CriteriaAPIを使用して以下のコードを試すことができます。私は試していませんが、それに応じてコードを変更してみることができます。
CriteriaBuilder cb = mediationEntityManager.getCriteriaBuilder();
CriteriaQuery<Table1> query = cb.createQuery(Table1.class);
Root<Table1> table1 = query.from(Table1.class);
query.select(table1);
//--
Subquery<Table2> subquery = query.subquery(Table2.class);
Root<Table2> table2 = subquery.from(Table2.class);
subquery.select(table2);
//--
List<Predicate> subQueryPredicates = new ArrayList<Predicate>();
subQueryPredicates.add(cb.equal(table1.get(Table1_.name), table2.get(Table2_.name)));
subQueryPredicates.add(cb.equal(table1.get(Table1_.age), table2.get(Table2_.age)));
subQueryPredicates.add(cb.equal(table1.get(Table1_.education), table2.get(Table2_.education)));
subquery.where(subQueryPredicates.toArray(new Predicate[]{}));
//--
List<Predicate> mainQueryPredicates = new ArrayList<Predicate>();
mainQueryPredicates.add(cb.equal(table1.get(Table1_.name), "san");
mainQueryPredicates.add(cb.equal(table1.get(Table1_.age), "10");
mainQueryPredicates.add(cb.not(cb.exists(subquery)));
//--
query.where(mainQueryPredicates.toArray(new Predicate[]{}));
TypedQuery<Table1> typedQuery = mediationEntityManager.createQuery(query);
List<Table1> resultList = typedQuery.getResultList();
また、以下のJPQLクエリを試すこともできます。これは、理解、変更、およびデバッグが簡単です。
SELECT t1
FROM table1 t1,
table2 t2
WHERE t1.name = 'san'
AND t1.age = '10'
AND (t2.name <> t1.name
AND t2.education <> t1.education
AND t2.age <> t1.age);