是否可以使用Hibernate 5.3+ CriteriaBuilder添加嵌套的SELECT IN语句?
常规我想使用条件构建器创建以下SQL:
select * from ORDERS where sender='ABC' and receiver='DEF' and amount='500' and id IN (SELECT id FROM cc4.best_orders)
标准定义(cc4.best_orders是一个简单的sql视图):
public class BestOrders implements Criterion {
private static final String SQL_CRITERIA =
".id IN (SELECT id FROM cc4.best_orders) ";
@Override
public TypedValue[] getTypedValues(Criteria criteria,
CriteriaQuery criteriaQuery) {
return new TypedValue[] {};
}
@Override
public String toSqlString(Criteria criteria, CriteriaQuery criteriaQuery) {
return criteriaQuery.getSQLAlias(criteria) + SQL_CRITERIA;
}
}
客户电话:
//...Old deprecated working way
Criteria crit = getSession().createCriteria(Order.class);
crit.add(getRestriction("sender.id", sender));
crit.add(getRestriction("receiver.id", receiver));
crit.add(getRestriction("amount.id", dataType));
crit.add(new BestOrders());
crit.setReadOnly(true);
Order order = (Order) crit.uniqueResult();
//...New Hibernate 5.3+ way
CriteriaBuilder cb = getSession().getCriteriaBuilder();
CriteriaQuery<Order> cr = cb.createQuery(Order.class);
Root<Order> root = cr.from(Order.class);
cr.select(root).where(
cb.and(
getEqualPredicate(root, cb, "sender.id", sender),
getEqualPredicate(root, cb, "receiver.id", receiver),
getEqualPredicate(root, cb, "amount.id", dataType)
//new BestOrders() ----> how to add 'SELECT IN' here ?!
)
);
Query<Order> query = getSession().createQuery(cr);
Order order = query.uniqueResult();
答案 0 :(得分:0)
吃完所有可能的JPA手册后,我找到了正确的方法(使用JPA子查询功能):
CriteriaBuilder cb = getEntityManager().getCriteriaBuilder();
CriteriaQuery<Order> orderCriteriaQuery = cb.createQuery(Order.class);
Root<Order> orderRoot = orderCriteriaQuery.from(Order.class);
Subquery<String> bestOrdersSubQuery = orderCriteriaQuery.subquery(String.class);
Root<BestOrders> bestOrdersRoot = bestOrdersSubQuery.from(BestOrders.class);
bestOrdersSubQuery.select(bestOrdersRoot.get("id"));
orderCriteriaQuery.select(orderRoot).where(
cb.and(
getEqualPredicate(cb, orderRoot.get("sender").get("id"), sender),
getEqualPredicate(cb, orderRoot.get("receiver").get("id"), receiver),
getEqualPredicate(cb, orderRoot.get("amount").get("id"), dataType),
orderRoot.get("id").in(
bestOrdersSubQuery
)
)
);
TypedQuery<Order> query = getEntityManager().createQuery(orderCriteriaQuery);
Order orderConfig = query.getSingleResult();
祝你好运!