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
,否则返回expr3
if(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();
};
}