0

是否可以使用 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();


需要学说/dbal

composer require doctrine/dbal

写一个新的迁移并写这个

 public function up()
    {
        Schema::table('table_name', function (Blueprint $table) {
            $table->integer('language_id')->change();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::table('your_table_name', function (Blueprint $table) {
            $table->dropColumn('language_id');
        });
    }

4

1 回答 1

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();

祝你好运!

于 2019-11-15T08:20:52.597 回答