spring中的分页查询

一.Spring中的分页对象

1.@PageableDefault

可放置在参数中,为Pageable对象指定默认值和排序方式

@GetMapping("/")
public String index(
    // size: 每一页显示的数据数量
    // sort: 排序的依据
    // direction: 排序的方式
    @PageableDefault(size = 5,sort = {"updateTime"},direction = Sort.Direction.DESC) 		Pageable pageable,
    Model model
    ){
    	// 返回前端的分页对象Page
        Page<Blog> listBlog = blogService.listBlog(pageable);

        toIndex(model,listBlog);

        return "index";
    }

2.Pageable接口

多用来和SpringDataJPA结合,进行分页查询,返回结果就是一个Page分页对象

前端根据搜索条件进行分页查询,后端用一个对象来封装前端的查询条件,进行分页条件查询

封装的前端查询条件对象

// 博客查询的封装对象
public class BlogQuery {
	
    private String title;  // 根据博客标题查询
    private Long typeId;  // 根据博客的分类id查询
    private boolean recommend;  // 根据是否推荐查询
    // ......
}

controller层

@PostMapping("/blogs/search")
public String search(
    // 指定默认的分页方式
    @PageableDefault(size = 10,sort = {"updateTime"},direction = Sort.Direction.DESC) 		Pageable pageable,
    BlogQuery blog,  // 前端的查询条件对象
    Model model
    ){
        model.addAttribute("page",blogService.listBlog(pageable, blog));
        // 定义一个片段,实现局部的渲染
        return "admin/blogs :: blogList";
    }

service层

@Override
public Page<Blog> listBlog(Pageable pageable, BlogQuery blog) {

    Specification<Blog> blogSpecification = new Specification<Blog>() {
        @Override
        public Predicate toPredicate(Root root, CriteriaQuery cq, CriteriaBuilder cb) {

            ArrayList<Predicate> predicateList = new ArrayList<>();
            // 判断是否有标题的条件传输过来(标题不等于空或者null的时候才会拼接条件)
            if (!"".equals(blog.getTitle()) && blog.getTitle() != null ){
                predicateList.add(cb.like(root.<String>get("title"), "%" +                               blog.getTitle() + "%"));
            }

            // 根据Blog对象中的Type对象的id值进行查询
            // 因为id是Long类型的,所以不存在空格字符串的情况
            if (blog.getTypeId() != null){
                predicateList.add(cb.equal(root<Type>get("type").get("id"),
                blog.getTypeId()));
            }

            // 判断是否是推荐的文章,是true的情况就进行查询
            if (blog.isRecommend()){
                predicateList.add(cb.equal(root.<Boolean>get("recommend"),
                blog.isRecommend()));
            }

            // 把条件列表转换成数组
            Predicate[] predicates = predicateList.toArray(
                new Predicate[predicateList.size()]
            );
            // 通过条件数据进行查询
            cq.where(predicates);

            return null;
        }
    };
	
    // 进行分页条件查询
    Page<Blog> all = repository.findAll(blogSpecification, pageable);

    return all;
}

前端使用Page分页对象获取数据分页数据

// 获取博客的总的条数
<h2 class="ui orange header" th:text="${page.totalElements}">14</h2>

// 获取分页对象中的每一个blog对象
<div class="ui padded vertical segment" th:each="blog : ${page.content}">

// 如果页数大于1页的话,就进行显示
<div class="ui bottom attached segment" th:if="${page.totalPages}>1">    

// 点击上一页的时候当前页数-1     只有存在上一页的情况下,上一页的按钮才会显示
<a href="#" th:href="@{/(page=${page.number}-1)}" th:unless="${page.first}">上一页</a>

// 点击下一页的时候当前页数+1     只有存在下一页的情况下,下一页的按钮才会显示
<a href="#" th:href="@{/(page=${page.number}+1)}" th:unless="${page.last}">下一页</a>

3.new PageImpl<>构造分页对象

PageImpl extends Chunk implements Page

PageImpl 是 Page接口的一个实现类

/*
	参数一: 通过分页查询查询到的对象
	参数二: 分页对象
	参数三: 对象(不是分页对象)的总的数量
*/
new PageImpl<>(arrayList, pageable, count);

示例

private Page<CommentAndBlog> returnResult (Page<Comment> commentList,Pageable pageable){
    ArrayList<CommentAndBlog> arrayList = new ArrayList<>();
    for (Comment comment : commentList) {
        CommentAndBlog commentAndBlog = new CommentAndBlog();
        commentAndBlog.setNickname(comment.getNickname());
        commentAndBlog.setContent(comment.getContent());
        commentAndBlog.setCreateTime(comment.getCreateTime());
        // 封装评论的id(为删除或者编辑id的时候使用)
        commentAndBlog.setId(comment.getId());

        // 封装评论所对应的文章
        Long blogId = comment.getBlog().getId();
        // 根据文章id查找文章的标题
        String blogTitle = blogService.getBlog(blogId).getTitle();
        commentAndBlog.setTitle(blogTitle);

        // 把构造好的对象添加到集合中
        arrayList.add(commentAndBlog);
    }
	
    // 获取查询对象的总的数量(非分页查询对象)
    long count = commentRepository.count();

    // 通过PageImpl<> 构造分页对象
    /*
         * 参数一: 查询到的对象
         * 参数二: 分页对象
         * 参数三: 数据的总的数量
         * */
    Page<CommentAndBlog> commentAndBlogs = new PageImpl<>(arrayList, pageable, count);
    return commentAndBlogs;
}

4.PageRequest.of()构造分页查询对象

参数一: 从第几页开始查询,当前为从第一页开始查询(写作0)

参数二: 每页显示的条数

参数三: 排序方式

PageRequest.of(0, size, sort);

@Override
public List<Blog> listRecommendBlogTop(Integer size) {
	// 构造排序对象
    Sort sort = new Sort(Sort.Direction.DESC, "updateTime");
    Pageable pageable = PageRequest.of(0, size, sort);
	
    // 根据分页对象,进行分页查询
    return repository.findTop(pageable);
}

你可能感兴趣的:(spring)