Specification动态查询
Spring Data JPA在实际业务中很多场景需要支持动态查询。比如前端查询功能提供了很多查询条件,用户可以根据一部分条件进行查询,那么后端就需要支持可配置的查询服务。
Spring Data JPA是支持动态查询,需要我们的repo继承JpaSpecificationExecutor接口,使用的时候传入相应参数即可。
查询方法
//查询单个
Optional<T> findOne(@Nullable Specification<T> var1)
//查询列表
List<T> findAll(@Nullable Specification<T> var1);
//查询分页,Pageable为分页参数
Page<T> findAll(@Nullable Specification<T> var1, Pageable var2);
//排序
List<T> findAll(@Nullable Specification<T> var1, Sort var2);
//查询总条数
long count(@Nullable Specification<T> var1);
Specification:查询条件
自定义我们自己的specification实现类,实现toPredicate(Root<TabUser> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder )方法。
第一个参数root:存放查询的参数。
第二个参数criteriaQuery:自定义查询方式,一般不用。
第三个参数criteriaBuilder :构造查询条件。
示例
定义一个repo继承接口JpaSpecificationExecutor
package com.dk.interfaces;
import com.dk.pojo.TabUser;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
public interface UserDao extends JpaRepository<TabUser,Integer>, JpaSpecificationExecutor<TabUser> {
}
根据用户名查询:
@RequestMapping("testSpec")
@ResponseBody
public void testSpec(){
Specification<TabUser> spec = new Specification<TabUser>() {
@Override
public Predicate toPredicate(Root<TabUser> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb) {
//获取比较的属性
Path<Object> userName = root.get("userName");
//构建查询条件
Predicate p = cb.equal(userName, "小黑");
return p;
}
};
List<TabUser> all = userDao.findAll(spec);
System.out.println(all);
}
根据用户名和用户id查询:
@RequestMapping("testSpec")
@ResponseBody
public void testSpec(){
Specification<TabUser> spec = new Specification<TabUser>() {
@Override
public Predicate toPredicate(Root<TabUser> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb) {
//获取比较的属性
Path<Object> userName = root.get("userName");
Path<Object> userId = root.get("userId");
//构建查询条件
Predicate p = cb.equal(userName, "小黑");
Predicate p2 = cb.equal(userId, "1");
// 将两个查询条件联系起来and或者是or
Predicate and = cb.and(p, p2);
return and;
}
};
List<TabUser> all = userDao.findAll(spec);
System.out.println(all);
}
根据用户名模糊查询:
@RequestMapping("testSpec")
@ResponseBody
public void testSpec(){
Specification<TabUser> spec = new Specification<TabUser>() {
@Override
public Predicate toPredicate(Root<TabUser> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb) {
//获取比较的属性
Path<Object> userName = root.get("userName");
//构建查询条件
Predicate p = cb.like(userName.as(String.class),"小%