ما يلي هو الاستعلام عن المعايير بخصوص NOT IN()
(ومع ذلك ، أفضل NOT EXISTS()
خلال NOT IN()
).
CriteriaBuilder criteriaBuilder=entityManager.getCriteriaBuilder();
CriteriaQuery<Colour>criteriaQuery=criteriaBuilder.createQuery(Colour.class);
Metamodel metamodel = entityManager.getMetamodel();
EntityType<Colour> entityType = metamodel.entity(Colour.class);
Root<Colour> root = criteriaQuery.from(entityType);
criteriaQuery.select(root);
Subquery<Long>subquery=criteriaQuery.subquery(Long.class);
Root<Product> subRoot = subquery.from(Product.class);
subquery.select(root.get(Colour_.colourId));
Predicate paramPredicate = criteriaBuilder.equal(subRoot.get(Product_.prodId), prodId);
Predicate correlatePredicate = criteriaBuilder.equal(root.get(Colour_.productSet), subRoot);
subquery.where(criteriaBuilder.and(paramPredicate, correlatePredicate));
criteriaQuery.where(criteriaBuilder.in(root.get(Colour_.colourId)).value(subquery).not());
criteriaQuery.orderBy(criteriaBuilder.desc(root.get(Colour_.colourId)));
TypedQuery<Colour> typedQuery = entityManager.createQuery(criteriaQuery);
List<Colour> list=typedQuery.getResultList();
هذا ينتج استعلام SQL التالي.
SELECT t0.colour_id, t0.colour_hex, t0.colour_name
FROM projectdb.colour t0
WHERE NOT
(t0.colour_id IN (
SELECT t0.colour_id
FROM prod_colour t3, projectdb.product t2, projectdb.product t1
WHERE (((t1.prod_id = ?)
AND (t1.prod_id = t2.prod_id))
AND ((t3.colour_id = t0.colour_id)
AND (t2.prod_id = t3.prod_id)))))
ORDER BY t0.colour_id DESC
هذا الاستعلام يعيد مجموعة النتائج المطلوبة. ومع ذلك ، فإنه ينتج صلة زائدة كما يمكن أن نرى ولكن يبدو أن هذا هو حشرة.
يحرر:
محاولة نفس الاستعلام على السبات ، تبدو طريقة كتابة هذا الاستعلام المعايير غير صحيحة. مجموعة من الانضمام والاستماع الفرعي يؤدي إلى إنتاج استعلام SQL الصحيح.
CriteriaBuilder criteriaBuilder=entityManager.getCriteriaBuilder();
CriteriaQuery<Colour>criteriaQuery=criteriaBuilder.createQuery(Colour.class);
Metamodel metamodel = entityManager.getMetamodel();
EntityType<Colour> entityType = metamodel.entity(Colour.class);
Root<Colour> root = criteriaQuery.from(entityType);
criteriaQuery.select(root);
Subquery<Long>subquery=criteriaQuery.subquery(Long.class);
Root<Colour> subRoot = subquery.from(Colour.class);
subquery.select(subRoot.get(Colour_.colourId));
SetJoin<Colour, Product> join = subRoot.join(Colour_.productSet, JoinType.INNER);
ParameterExpression<Long> parameterExpression=criteriaBuilder.parameter(Long.class);
criteriaQuery.where(criteriaBuilder.in(root.get(Colour_.colourId)).value(subquery).not());
subquery.where(criteriaBuilder.equal(join.get(Product_.prodId), parameterExpression));
criteriaQuery.orderBy(criteriaBuilder.desc(root.get(Colour_.colourId)));
TypedQuery<Colour> typedQuery = entityManager.createQuery(criteriaQuery);
List<Colour> list = typedQuery.setParameter(parameterExpression, 1L).getResultList();
هذا ينتج استعلام SQL التالي والذي من شأنه أن يتم تفويض بدوره إلى MySQL.
SELECT t0.colour_id, t0.colour_name, t0.colour_hex
FROM projectdb.colour t0
WHERE NOT (t0.colour_id IN
(SELECT t1.colour_id
FROM prod_colour t3, projectdb.product t2, projectdb.colour t1
WHERE ((t2.prod_id = ?)
AND ((t3.colour_id = t1.colour_id)
AND (t2.prod_id = t3.prod_id)))))
ORDER BY t0.colour_id DESC