【问题标题】:Modify CriteriaQuery JOINs after they have been added to the CriteriaQuery将 CriteriaQuery JOIN 添加到 CriteriaQuery 后修改它们
【发布时间】:2014-04-03 14:31:32
【问题描述】:

目前,我有一个UserDao 类,它使用CriteriaQuery 创建一个查询,例如,使用它的ID 从数据库中检索User 的一个实例(我们称该方法为findById)。到目前为止,它非常简单,而且效果很好。

不过,我还有一个GenericDao,它是由UserDao 扩展的。在userDao.findById 返回结果之前,它会将criteriaQuery 传递给GenericDao,因此我可以对criteriaQuery 添加一些限制。

例子:

public class GenericDao
{
    private EntityManager entityManager;

    protected Object executeCriteriaQuery(CriteriaQuery criteriaQuery)
    {
        return entityManager.createQuery(prepareQuery(criteriaQuery)).getSingleResult();
    }

    private CriteriaQuery prepareQuery(CriteriaQuery criteriaQuery)
    {
        // add restrictions to criteriaQuery
        Predicate predicate = ... // some predicate which will be appended to the already formed criteriaQuery

        criteriaQuery.where(criteriaBuilder.and(criteriaQuery.getRestriction(), predicate));

        return criteriaQuery;
    }
}

public class UserDao extends GenericDao
{
    public User findById(String id)
    {
        CriteriaQuery query = criteriaBuilder.createQuery(entityClass);
        Root<P> entity = query.from(entityClass);
        query.select(entity);
        query.where(criteriaBuilder.equal(entity.get("id"), id.toUpperCase()));

        return executeCriteriaQuery(query);
    }
}

问题是:在扩展我的GenericDao 的 DAO 中构建的查询可能包含JOIN。我想向 JOIN 添加一个谓词,该谓词添加到 criteriaQuery
据我所知,我可以使用From.getJoins() 在查询中检索JOINs。但是,根据该方法的 Javadoc:

返回已从此绑定类型进行的连接。如果没有从此绑定类型进行连接,则返回空集。 对集合的修改不会影响查询。

返回:由这种类型组成的连接

如何在criteriaQueryJOIN 子句中添加谓词?

【问题讨论】:

  • 是什么阻止您在具体的 DAO 类中构建/修改条件查询,然后使用 GenericDao 执行这些查询?这种方法可以更好地解耦职责并将业务逻辑转移到具体的 DAO,即GenericDao 可以是具有抽象prepareQuery 方法的抽象类,目前还不是完全通用的。
  • @wypieprz 我希望能够在查询中添加适用于每个 DAO 中构建的每个查询的子句,这就是为什么我想在我的 GenericDao 中实现它的原因。如果我在每个班级都这样做,那么每个 DAO 中的每个查询都会使用相同的代码。

标签: java jpa-2.0 criteria criteria-api


【解决方案1】:

一段时间后,我决定对这个特定问题采用不同的方法。由于我找不到有关如何执行此操作的任何选项,因此我尝试在 JPA 实现级别上解决它。由于我使用的是 Hibernate,所以我使用了Hibernate filters。对于 Eclipselink 用户:您可以使用 Eclipselink 的Multi tenancy 功能。

不幸的是,我还没有找到更高层次的解决方案,所以如果我要切换实现,我仍然必须为此编写一个新的实现。另一方面,我可能不会定期切换到新的实现,所以这可能不会成为问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-11
    • 2014-07-15
    • 2016-06-21
    • 2014-02-22
    • 1970-01-01
    • 2013-02-10
    • 1970-01-01
    相关资源
    最近更新 更多