JpaSpecificationExecutor接口
概述
封装 JPA Criteria 查询条件。通常使用匿名内部类的方式来创建该接口的对象
接口使用方式——Repository
public interface TaskPlanRepository extends JpaRepository<TaskPlan, String>, JpaSpecificationExecutor<TaskPlan> {
}简单查询场景
public interface SpecificationExecutorRepository extends CrudRepository<User, Integer>,
JpaSpecificationExecutor<User> {
}@Service
public class SpecificationExecutorRepositoryManager {
@Autowired
private SpecificationExecutorRepository dao;
/**
* 描述:根据name来查询用户
*/
public User findUserByName(final String name){
return dao.findOne(new Specification<User>() {
@Override
public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query,
CriteriaBuilder cb) {
Predicate predicate = cb.equal(root.get("name"), name);
return predicate;
}
});
}
/**
* 描述:根据name和email来查询用户
*/
public User findUserByNameAndEmail(final String name, final String email){
return dao.findOne(new Specification<User>() {
@Override
public Predicate toPredicate(Root<User> root,
CriteriaQuery<?> query, CriteriaBuilder cb) {
List<Predicate> list = new ArrayList<Predicate>();
Predicate predicate1 = cb.equal(root.get("name"), name);
Predicate predicate2 = cb.equal(root.get("email"), email);
list.add(predicate1);
list.add(predicate2);
// 注意此处的处理
Predicate[] p = new Predicate[list.size()];
return cb.and(list.toArray(p));
}
});
}
/**
* 描述:组合查询
*/
public User findUserByUser(final User userVo){
return dao.findOne(new Specification<User>() {
@Override
public Predicate toPredicate(Root<User> root,
CriteriaQuery<?> query, CriteriaBuilder cb) {
Predicate predicate = cb.equal(root.get("name"), userVo.getName());
cb.and(predicate, cb.equal(root.get("email"), userVo.getEmail()));
cb.and(predicate, cb.equal(root.get("password"), userVo.getPassword()));
return predicate;
}
});
}
/**
* 描述:范围查询in方法,例如查询用户id在[2,10]中的用户
*/
public List<User> findUserByIds(final List<Integer> ids){
return dao.findAll(new Specification<User>() {
@Override
public Predicate toPredicate(Root<User> root,
CriteriaQuery<?> query, CriteriaBuilder cb) {
return root.in(ids);
}
});
}
/**
* 描述:范围查询gt方法,例如查询用户id大于9的所有用户
*/
public List<User> findUserByGtId(final int id){
return dao.findAll(new Specification<User>() {
@Override
public Predicate toPredicate(Root<User> root,
CriteriaQuery<?> query, CriteriaBuilder cb) {
return cb.gt(root.get("id").as(Integer.class), id);
}
});
}
/**
* 描述:范围查询lt方法,例如查询用户id小于10的用户
*/
public List<User> findUserByLtId(final int id){
return dao.findAll(new Specification<User>() {
@Override
public Predicate toPredicate(Root<User> root,
CriteriaQuery<?> query, CriteriaBuilder cb) {
return cb.lt(root.get("id").as(Integer.class), id);
}
});
}
/**
* 描述:范围查询between方法,例如查询id在3和10之间的用户
*/
public List<User> findUserBetweenId(final int start, final int end){
return dao.findAll(new Specification<User>() {
@Override
public Predicate toPredicate(Root<User> root,
CriteriaQuery<?> query, CriteriaBuilder cb) {
return cb.between(root.get("id").as(Integer.class), start, end);
}
});
}
/**
* 描述:排序和分页操作
*/
public Page<User> findUserAndOrder(final int id){
Sort sort = new Sort(Direction.DESC, "id");
return dao.findAll(new Specification<User>() {
@Override
public Predicate toPredicate(Root<User> root,
CriteriaQuery<?> query, CriteriaBuilder cb) {
return cb.gt(root.get("id").as(Integer.class), id);
}
}, new PageRequest(0, 5, sort));
}
/**
* 描述:只有排序操作
*/
public List<User> findUserAndOrderSecondMethod(final int id){
return dao.findAll(new Specification<User>() {
@Override
public Predicate toPredicate(Root<User> root,
CriteriaQuery<?> query, CriteriaBuilder cb) {
cb.gt(root.get("id").as(Integer.class), id);
query.orderBy(cb.desc(root.get("id").as(Integer.class)));
return query.getRestriction();
}
});
}
}复杂查询场景
分页查询
实现sql条件">=" 和 "<="的用法
greaterThanOrEqualTo代表 >= 当前条件时间, lessThanOrEqualTo代表<=当前条件时间,具体代码实现,参考上面的项目分页代码
实现sql条件“=”的用法
equal的用法,详细参考上面的项目分页代码
同样的不要忘记notEqual方法
实现sql条件“in”的用法
也是一整块分页代码,其中,in的使用方式,是我们关注的要点如下:
通过循环获取值,放到in的属性值里,在最后通过cb.or(in) 连接使用,打印的部分SQL如下:
关联查询的用法
root.join("workManage2") 连接的是当前对象的关联属性对象,创建一个Join对象,就可以通过该join对象,通过查询条件,关联查询数据,具体使用,参考上面的作品分页查询代码
关联实体类查询,就是关联Id查询
实现sql条件“or”的用法、"like"的用法
根据上面的招标分页查询,or、like的用法如下:
具体实现参考招标分页查询实现
排序用法
上面的是通过CriteriaBuilder实现排序,也可以通过Pageable的方式实现
具体实现参考招标分页查询实现、项目分页查询实现
Last updated
Was this helpful?