SpringBoot分页功能实现原理(非工具,主后端)

效果图如下
在这里插入图片描述在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
1,创建实体类,分页信息类PaginationDTO和每页显示的数据的实体类QuestionDTO,在PaginationDTO中注入QuestionDTO以实现关联。
QuestionDTO类:

@Data
public class QuestionDTO {
    private Integer id;
    private String title;
    private String description;
    private String tag;
    private long gmtCreate;
    private long gmtModified;
    private Integer creator;
    private Integer viewCount;
    private Integer commentCount;
    private Integer likeCount;
    private User user;
}

PaginationDTO类:

@Data
public class PaginationDTO {
    private List<QuestionDTO> questionDTOS;
    private boolean showPrevious;
    private boolean showFirstPage;
    private boolean showNext;
    private boolean showEndPage;
    private Integer totalPage;
    private Integer page;
    private List<Integer> pages=new ArrayList<>();
     public void setPagination(Integer totalCount, Integer page, Integer size) {
     ……
     ……
     ……
     }
  
}

2,从前端page(页码)和size(每页显示的数据数)的值(需要设置默认值,page=1,size=5(这个值可以随意)),后端用Controller层拦截接收,调用Service层方法先利用page和size查询出需要显示的数据、总数据数(用来计算总页数),其Mapper方法如下:

在这里插入代码片
@Mapper
public interface QuestionMapper {
    @Select("select * from question limit #{offset},#{size}")
    List<Question> list(@Param("offset") Integer offset, @Param("size") Integer size);

    @Select("select count(1) from question")
    Integer count();
}

然后,将查询出来的QuestionDTO 集合set到PaginationDTO中,并把查询出的totalCount(总记录数)、size、page传到分页的方法中实现分页(分页的方法是上面PaginationDTO类中 public void setPagination(Integer totalCount, Integer page, Integer size)方法中)。
方法如下

		paginationDTO.setQuestionDTOS(questionDTOArrayList);
        Integer totalCount = questionMapper.count();
        paginationDTO.setPagination(totalCount,page,size);
  public void setPagination(Integer totalCount, Integer page, Integer size) {
        totalPage=(totalCount+size-1)/size;
        if (totalPage==0){
            showPrevious=false;
            showFirstPage=false;
            showNext=false;
            showEndPage=false;
            totalPage=1;
            return;
        }
        if (page<1){
            page=1;
        }
        if (page>totalPage){
            page=totalPage;
        }
        this.page=page;
        pages.add(page);
        for (int i=1;i<=3;i++){
            if (page-i>0){
                pages.add(0,page-i);
            }
            if (page+i<=totalPage){
                pages.add(page+i);
            }
        }
        //是否展示上一页
        if (page==1){
            showPrevious=false;
        }else {
            showPrevious=true;
        }
        //是否展示下一页
        if (page==totalPage){
            showNext=false;
        }else {
            showNext=true;
        }
        //是否展示第一页
        if (pages.contains(1)){
            showFirstPage=false;
        }else {
            showFirstPage=true;
        }
        //是否展示最后一页
        if (pages.contains(totalPage)){
            showEndPage=false;
        }else {
            showEndPage=true;
        }
    }

整个Service层方法结构为:

@Service
public class QuestionService {
    @Autowired
    private QuestionMapper questionMapper;
    @Autowired
    private UserMapper userMapper;

    public PaginationDTO list(Integer page, Integer size) {
        Integer offset=size*(page-1);
        List<Question> questions = questionMapper.list(offset,size);
        ArrayList<QuestionDTO> questionDTOArrayList  = new ArrayList<>();
        PaginationDTO paginationDTO = new PaginationDTO();
        for (Question question : questions) {
           User user= userMapper.findById(question.getCreator());
            QuestionDTO questionDTO = new QuestionDTO();
            BeanUtils.copyProperties(question,questionDTO);
            questionDTO.setUser(user);
            questionDTOArrayList.add(questionDTO);
        }
        paginationDTO.setQuestionDTOS(questionDTOArrayList);
        Integer totalCount = questionMapper.count();
        paginationDTO.setPagination(totalCount,page,size);
        return paginationDTO;
    }
}

Controller层调用这个service的list方法便可返回PaginationDTO 对象,然后利用Model将数据传输到前端

 PaginationDTO paginationDTO=questionService.list(page,size);
        model.addAttribute("pagination",paginationDTO);

Controller层代码如下

@Controller
public class IndexCotroller {
    @Autowired
    private UserMapper  userMapper;
    @Autowired
    private QuestionService questionService;
    @GetMapping("/")
    public String IndexController(HttpServletRequest request, Model model,
              @RequestParam(name="page",defaultValue="1") Integer page,
              @RequestParam(name="SIZE",defaultValue="5") Integer size){
        PaginationDTO paginationDTO=questionService.list(page,size);
        model.addAttribute("pagination",paginationDTO);
        return "index";
        }
}

前端页面编写。
前端引入thymeleaf:
在pom.xml中引入依赖

		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

引入BootStrap:

 <link rel="stylesheet" href="http://cdn.static.runoob.com/libs/bootstrap/3.3.7/css/bootstrap.min.css">
    <script src="http://cdn.static.runoob.com/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="http://cdn.static.runoob.com/libs/bootstrap/3.3.7/js/bootstrap.min.js"></script>

用Model 页面交互方法中存的pagination传递数据
model.addAttribute(“pagination”,paginationDTO);
中传来的遍历问题内容

 <div class="media" th:each="question:${pagination.questionDTOS}" th:if="${pagination.questionDTOS!=null}">
                    <div class="media-left">
                        <a href="#">
                            <img class="media-object img-thumbnail" th:src="${question.user.avatarUrl}">
                        </a>
                    </div>
                    <div class="media-body" >
                        <h4 class="media-heading" th:text="${question.title}"></h4>
                        <span th:text="${question.description}"></span><br>
                        <p class="text-muted"><span th:text="${question.commentCount}"></span> 个回复· <span th:text="${question.viewCount}"></span> 次浏览·
                            <span th:text="${#dates.format(question.gmtCreate,'yyyy-MM-dd HH:mm')}"></span> </p>
                    </div>
                </div>

分页的显示:

<nav aria-label="Page navigation" style="float: right">
                    <ul class="pagination">
                        <li th:if="${pagination.showFirstPage}">
                            <a href="/?page=1" aria-label="Previous">
                                <span aria-hidden="true">&lt;&lt;</span>
                            </a>
                        </li>
                        <li th:if="${pagination.showPrevious}">
                            <a th:href="@{/(page=${pagination.page - 1})}" aria-label="Previous">
                                <span aria-hidden="true">&lt;</span>
                            </a>
                        </li>
                        <li th:each="page:${pagination.pages}" th:class="${pagination.page==page}?'active':''">
                            <a th:text="${page}" th:href="@{/(page=${page})}"></a></li>
                        <li th:if="${pagination.showNext}">
                            <a th:href="@{/(page=${pagination.page + 1})}" aria-label="Next">
                                <span aria-hidden="true">&gt;</span>
                            </a>
                        </li>
                        <li th:if="${pagination.showEndPage}">
                            <a th:href="@{/(page=${pagination.totalPage})}" aria-label="Next">
                                <span aria-hidden="true">&gt;&gt;</span>
                            </a>
                        </li>
                    </ul>
                </nav>

整个index.html页面如下

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>超超社区</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <link rel="stylesheet" href="http://cdn.static.runoob.com/libs/bootstrap/3.3.7/css/bootstrap.min.css">
    <script src="http://cdn.static.runoob.com/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="http://cdn.static.runoob.com/libs/bootstrap/3.3.7/js/bootstrap.min.js"></script>
    <link rel="stylesheet" href="../static/css/community.css">

</head>
<body>
<nav class="navbar navbar-default" >
    <div th:insert="~{navigation :: navigation}"></div>
    <div class="container-fluid main" id="main">
        <div class="row">
            <div class="col-lg-9 col-md-12 col-sm-12 col-xs-12 "  style="border-right: 5px solid #efefef ">
                <h2> <span class="glyphicon glyphicon-list" aria-hidden="true"></span>&nbsp;发现</h2>
                <hr>
                <div class="media" th:each="question:${pagination.questionDTOS}" th:if="${pagination.questionDTOS!=null}">
                    <div class="media-left">
                        <a href="#">
                            <img class="media-object img-thumbnail" th:src="${question.user.avatarUrl}">
                        </a>
                    </div>
                    <div class="media-body" >
                        <h4 class="media-heading" th:text="${question.title}"></h4>
                        <span th:text="${question.description}"></span><br>
                        <p class="text-muted"><span th:text="${question.commentCount}"></span> 个回复· <span th:text="${question.viewCount}"></span> 次浏览·
                            <span th:text="${#dates.format(question.gmtCreate,'yyyy-MM-dd HH:mm')}"></span> </p>
                    </div>
                </div>
                <hr>
                <nav aria-label="Page navigation" style="float: right">
                    <ul class="pagination">
                        <li th:if="${pagination.showFirstPage}">
                            <a href="/?page=1" aria-label="Previous">
                                <span aria-hidden="true">&lt;&lt;</span>
                            </a>
                        </li>
                        <li th:if="${pagination.showPrevious}">
                            <a th:href="@{/(page=${pagination.page - 1})}" aria-label="Previous">
                                <span aria-hidden="true">&lt;</span>
                            </a>
                        </li>
                        <li th:each="page:${pagination.pages}" th:class="${pagination.page==page}?'active':''">
                            <a th:text="${page}" th:href="@{/(page=${page})}"></a></li>
                        <li th:if="${pagination.showNext}">
                            <a th:href="@{/(page=${pagination.page + 1})}" aria-label="Next">
                                <span aria-hidden="true">&gt;</span>
                            </a>
                        </li>
                        <li th:if="${pagination.showEndPage}">
                            <a th:href="@{/(page=${pagination.totalPage})}" aria-label="Next">
                                <span aria-hidden="true">&gt;&gt;</span>
                            </a>
                        </li>
                    </ul>
                </nav>
            </div>
        </div>
    </div>
</nav>
</body>
</html>

这样分页显示的功能就完成啦!!!(撒花)


版权声明:本文为qq_43223954原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。