1、使用@Query
public interface UserRepository extends JpaRepository<User,Long> {
//字符串类型在 mysql 为 null 时,为 '' 字符串,如果为空,就使用 1 = 1 条件去查询
@Query(value = "select * from people where if(?1 !='',name like concat('%',?1,'%'),1=1) and if(?2 !='',sex=?2,1=1)"+
" and if(IFNULL(?3,'') !='',age=?3,1=1) and if(IFNULL(?4,'') !='',num=?4,1=1) ",nativeQuery = true)
List<People> find(String name,String sex,Integer age,Integer num);
}
Tips:
nativeQuery = true的含义是使用原生SQL,即注解中的SQL语句会生效,false的话就不会生效。- SQL语句中
?1、?2、?3、?4的意思是代表方法中的第几个参数。 - SQL中模糊查询的写法为
like concat('%', ?1, '%') if(?1 !='',name like concat('%',?1,'%'),1=1)代表传入的参数name如果不为""(Spring类型空是""而不是null)将参数传入name,如果为空时显示1 = 1代表参数为真,对查询结果不产生作用。IF的语法满足mysql的基本语法,IF(expr1,expr2,expr3), 如果expr1为真(expr1 <> 0以及expr1 <> NULL),那么IF()返回expr2,否则返回expr3if(IFNULL(?3,'') !='',age=?3,1=1)表示如果传入的年龄是null,则替换成空字符串,然后判断是否为空,不为空则将参数传入age,否则忽略不对查询结果产生影响。IFNULL是mysql中的一个函数,这个函数一般用来替换NULL值的。IFNULL(value1,value2),判断value1是否为null,如果为null则用value2替换- 参数定义时,定义数值,应使用
Integer,如果用int定义,当入参为NULL时,程序会报空指针错误。原因是JAVA中int是值类型,非对象,不可以设置为NULL,integer是对象类型,可以设置为NULL。
2、使用Specification
@Override
public Specification<ProjectRiskSituation> findSpec(){
return (Root<ProjectRiskSituation> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) -> {
List<Predicate> listPredicate = new ArrayList<>();
try {
if(null != this.getStartFallDate() && !"".equals(this.getStartFallDate())){
Predicate p1 = criteriaBuilder.greaterThanOrEqualTo(root.get("fallDate"),this.getStartFallDate().split(" ")[0]);
listPredicate.add(p1);
}
if(null != this.getEndFallDate() && !"".equals(this.getEndFallDate())){
Predicate p2 = criteriaBuilder.lessThanOrEqualTo(root.get("fallDate"),this.getEndFallDate().split(" ")[0]);
listPredicate.add(p2);
}
}catch (Exception e) {
e.printStackTrace();
}
return criteriaBuilder.and(listPredicate.toArray(new Predicate[0]));
// 或 return query.where(listPredicate.toArray(new Predicate[0])).getRestriction();
};
}
本文介绍如何使用JPA中的@Query注解实现动态SQL查询,包括条件判断、模糊搜索等功能,并展示了通过Specification接口进行复杂查询条件组合的方法。
5826





