當使用JPA的Specification處理like查詢時,如果含有特殊字符%和_,則需要使用以下API處理問題:
hibernate-jpa-2.1-api-1.0.2.Final.jar
Predicate like(Expression<String> var1, String var2, char var3);
第三個參數是escape關鍵字,必須是char。
此api存在hibernate-jpa-2.1-api-1.0.2.Final.jar包的CriteriaBuilder中。
代碼如下:
Map para = new HashMap(); para.put("isSoftDel", 0); para.put("title", title); Sort sort = new Sort(Sort.Direction.DESC, "createTime"); Page pageInfo = repository.findAll(service.getSpecificationForPage(para), getPageable(limit, page, sort));
public Specification getSpecificationForPage(Map para) { return new Specification() { @Override public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder criteriaBuilder) { List<Predicate> list = new ArrayList<>(); Predicate predicate1 = criteriaBuilder.and(criteriaBuilder.equal(createBy, para.get("createBy"))); Predicate predicate2 = criteriaBuilder.and(criteriaBuilder.notEqual(createBy, para.get("createBy")), criteriaBuilder.equal(publishStatus, para.get("publishStatus"))); Predicate predicate = criteriaBuilder.or(predicate1, predicate2); list.add(predicate); JPAUtil.like(list, criteriaBuilder, root, "title", para); return criteriaBuilder.and(list.toArray(new Predicate[list.size()])); } }; }
public static void like(List<Predicate> predicates,CriteriaBuilder cb, Root<?> root, String colmun, Map para) { like(predicates,cb,root,colmun,para,colmun); } public static void like(List<Predicate> predicates,CriteriaBuilder cb, Root<?> root, String colmun, Map para,String paraKey) { if(!checkPara(paraKey,para)){ return; } try { String title = (String) para.get(paraKey); if(title.contains("_") || title.contains("%")){ //注:"\"被作為轉義字符時必須也被轉義 title = title.replace("\\","\\\\").replace("_","\\_").replace("%","\\%"); predicates.add(cb.like(root.get(colmun), "%" + title + "%",'\\')); }else{ predicates.add(cb.like(root.get(colmun), "%" + para.get(paraKey) + "%")); } } catch (Exception e) { e.printStackTrace(); predicates.add(cb.like(root.get(colmun), "%" + para.get(paraKey) + "%")); } }
在此做以記錄。