欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【JPA】Spring Data JPA 实现分页和条件查询

程序员文章站 2022-04-25 19:34:11
...

1、在Repository层继承两个接口

  • JpaRepository<Admin, Integer> 泛型参数:1.要查询的实体(Entity),2.这个实体的主键类型
  • JpaSpecificationExecutor 泛型参数:要查的实体
@Repository
public interface AdminRepository extends JpaRepository<Admin, Integer>, JpaSpecificationExecutor<Admin> {
}

2、在Service层进行查询操作

Query 是自定义的一个类,放着查询的条件

public Page<Book> findByPage(Query query) {
        //1.设置Page信息,参数1:当前页(下标从0开始),参数2:每页显示的个数
        PageRequest pageRequest = PageRequest.of(query.getPageNum() - 1, query.getPageSize());
        /**
        *	2.设置查询条件,实现
        */
        Specification<Book> specification = new Specification<Book>() {
            @Override
            public Predicate toPredicate(Root<Book> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb) {
                //用于暂时存放查询条件,存放到查询条件List中
                ArrayList<Predicate> predicateList = new ArrayList<>();
            	//第一个条件  like 语句
                if (!StringUtils.isEmpty(query.getName())) {
                    Predicate name = cb.like(root.get("name"), "%" + query.getName() + "%");
                    predicateList.add(name);
                }
                //第二个条件  like 语句
                if (!StringUtils.isEmpty(query.getAuthor())) {
                    Predicate author = cb.like(root.get("author"), "%" + query.getAuthor() + "%");
                    predicateList.add(author);
                }
                //第三个条件  like 语句
                if (!StringUtils.isEmpty(query.getPublishHouse())) {
                    Predicate publishHouse = cb.like(root.get("publishHouse"), "%" + query.getPublishHouse() + "%");
                    predicateList.add(publishHouse);
                }
                //第四个条件   like 语句
                if (!StringUtils.isEmpty(query.getType())) {
                    Predicate type = cb.like(root.get("type"), "%" + query.getType() + "%");
                    predicateList.add(type);
                }
                //第五个语句   between 语句
                if (query.getMinPrice() < query.getMaxPrice()) {      
                	//库中的 price 在getMinPrice 和 getMaxPrice 之间
                    Predicate price = cb.between(root.get("price"), query.getMinPrice(), query.getMaxPrice());
                    predicateList.add(price);
                }
				//第六个语句   大于等于
				if (query.getMinPrice() == 0 && query.getMaxPrice() == 0) {
                	// 库中的 price >=getMinPrice()
                    Predicate greaterEqual = cb.greaterThanOrEqualTo(root.get("price"), query.getMinPrice());
                    predicateList.add(greaterEqual);
                } 
					
				//条件语句都已经装到了 predicateList  集合里面  ,然后把这个类型的集合转为这个类型的数组
                Predicate[] predicates = new Predicate[predicateList.size()];
                //条件之间 OR 运算或and运算
                if ("or".equals(query.getSharpness())) {
                	//这个是数组中的所有条件之间进行的是  或  运算
                    return cb.or(predicateList.toArray(predicates));
                } else {
                	//这个是数组中的所有条件之间进行的是  与 运算
                    return cb.and(predicateList.toArray(predicates));
                }
            }
        };
        //使用  findAll 方法,第一个参数:条件的信息,第二个参数:分页信息
        //注意:这个方法必须要让bookRepository接口继承 JpaSpecificationExecutor接口(上面说的第二个)
        Page<Book> page = bookRepository.findAll(specification, pageRequest);
        //返回page对象
        return page;
    }

3、Page的方法

//从Controller层调用Service层的方法,拿到Page对象
Page<Book> page = bookService.findByPage(query);
//判断是否找到了实体
boolean b = page.hasContent();
//返回装着实体的List集合
List<Book> content = page.getContent();
//符合条件的条数(不是数据库所有的条数,也不是当前页的条数)
long totalElements = page.getTotalElements();
//总页数
int totalPages = page.getTotalPages();