使用 CriteriaQuery 进行复杂查询

Using CriteriaQuery for complex queries

假设以下查询:

 public List<UserEntity> search(String str, Integer page, Integer limit) {

        String sql = "SELECT u FROM UserEntity u  ";

        if (str.length() > 0) {
            sql += "INNER JOIN u.account a ";
        }

        sql += "WHERE 1 = 1 ";

        if (str.length() > 0) {
            sql += "AND LOWER(u.name) LIKE :str OR LOWER(u.surname) LIKE :str OR LOWER(a.email) LIKE :str ";
        }

        Query q = entityManager.createQuery(sql);

        if (str.length() > 0) {
            q.setParameter("str", str.toLowerCase() + "%");
        }

        q.setFirstResult(page * limit);
        q.setMaxResults(limit);
        return q.getResultList();

    }

如您所见,我们有两个条件,它们将决定 table 是否与另一个连接,以及是否存在某些 where 条件。此外,我们有 OR 条件,以便可以针对多个列(其中一列取自已加入的帐户 table)检查输入“str”。

现在我想用 CriteriaQuery 来写这个,但问题是我无法设法包含上面的所有条件。

终于想出了一个非常好的解决方案。 原来如此!

   public List<UserEntity> search(String str, Integer page, Integer limit) {

        CriteriaBuilder qb = entityManager.getCriteriaBuilder();
        CriteriaQuery<UserEntity> query = qb.createQuery(UserEntity.class);
        Root<UserEntity> root = query.from(UserEntity.class);
        query.select(root);

        if (str.length() > 0) {
            Predicate checkName = qb.equal(root.get("name"), str);
            Predicate checkSurname = qb.equal(root.get("surname"), str);
            Predicate checkEmail = qb.equal(root.get("account").get("email"), str);

            query.where(
                    qb.or( checkName, checkSurname, checkEmail)
            );
        }

        Query q = entityManager.createQuery(query);

        q.setFirstResult(page * limit);
        q.setMaxResults(limit);

        return q.getResultList();

    }