我目前已经实现了一个动态查询构建器,如果我的查询条件拼写正确,它可以很好地工作。由于情况可能并非总是如此,我需要一个足够灵活的解决方案,以便采取任何条件变化,主要是支持不区分大小写。
当前规范的toPredicate方法覆盖代码如下所示:
final List<Predicate> predicates = new ArrayList<Predicate>();
Path<String> username = root.get("username");
Path<String> agentCode = root.get("agentCode");
Path<EntityStatus> status = root.get("status");
Path<String> firstname = root.get("firstName");
Path<String> lastname = root.get("lastName");
Path<String> email = root.get("eMail");
if(criteria.getUsername()!=null && !criteria.getUsername().isEmpty()) {
predicates.add(cb.equal(username, criteria.getUsername()));
}
if(criteria.getAgentCode()!=null && !criteria.getAgentCode().isEmpty()) {
predicates.add(cb.equal(agentCode, criteria.getAgentCode()));
}
if(criteria.getFirstName()!=null && !criteria.getFirstName().isEmpty()) {
predicates.add(cb.like(firstname, "%"+criteria.getFirstName()+"%"));
}
if(criteria.getLastName()!=null && !criteria.getLastName().isEmpty()) {
predicates.add(cb.equal(lastname, criteria.getLastName()));
}
if(criteria.getEMail()!=null && !criteria.getEMail().isEmpty()) {
predicates.add(cb.equal(email, criteria.getEMail()));
}
if(criteria.getStatus()!=null) {
predicates.add(cb.equal(status, criteria.getStatus()));
}
return cb.and(predicates.toArray(new Predicate[predicates.size()]));
}
我从服务层调用的存储库接口如下所示。
public interface UserRepo extends PagingAndSortingRepository<User, Long> {
List<User> findAll(Specification spec);
}
感谢您的帮助
答案 0 :(得分:4)
正如@Nikolas Charalambidis建议的那样,我已经使用了他的答案的变体,这些变体适合我的确切实施。 答案只需要修改predacate.add()行。 有了这个答案,该解决方案足够灵活,可以支持不区分大小写和部分输入。
predicates.add(cb.like(cb.lower(email), "%"+criteria.getEMail().toLowerCase()+"%"));
答案 1 :(得分:2)
通常,您使用方法equalsIgnoreCase()来实现不区分大小写。
但是在这种情况下,您只需解析要比较的值而不实现比较本身。因此,您可以使用方法toLowerCase()以小写形式解析所有值,强制它们在不区分大小写的情况下进行比较。
predicates.add(cb.equal(email.toLowerCase(), criteria.getEMail().toLowerCase()));
编辑:我看了一下CriteriaBuilder的JavaEE文档,找到了可能有用的方法lower()。