使用 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();
}
假设以下查询:
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();
}