JPA+Springboot实现分页效果

时间:2020-01-09
本文章向大家介绍JPA+Springboot实现分页效果,主要包括JPA+Springboot实现分页效果使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

JPA+Springboot实现分页效果

后端

JPA 默认提供了一个分页类:org.springframework.data.domain.Page, 这个分页类已经能够满足各种分页需要了,所以大部分时候用它就足够了。但是除了一点,就是如图所示的,比如当前是第8页,前面要显示3个,后面要显示3个,总共7条分页点,这个类默认就不提供了。
所以我们做了一个 Page4Navigator, 首先对 Page 类进行了封装,然后在构造方法里提供了一个 navigatePages 参数。

navigatePages:导航需要的个数,这里设置为7,就表示如图所示的效果,前面3个,后面3个。

思路:

  • 当总页数小于或等于导航页码数时,就遍历现有的页码总数,这种最简单了。
  • 当总页数大于导航页码数(7)时,现在当前页num为8,就计算出开始数num - navigatePages / 2和结尾数num + navigatePages / 2,这种情况下分别为5和11,对开始数5使用for循环7次,就可以得到一个int 数组变量 navigatepageNums [5,6,7,8,9,10,11],方便前端遍历展示。

  • 异常处理:
    • 若起始值小于1时,则起始值设置为1,对着起始值循环7次startNum++得到数组
    • 若结尾值大于总条数时,则结尾值设置为总条数,数组索引设置为6(7-1),对着结尾值循环7次endNum--得到数组

工具类Page4Navigator

    private void calcNavigatepageNums() {
        int navigatepageNums[];
        int totalPages = getTotalPages();
        int num = getNumber();
        //当总页数小于或等于导航页码数时
        if (totalPages <= navigatePages) {
            navigatepageNums = new int[totalPages];
            for (int i = 0; i < totalPages; i++) {
                navigatepageNums[i] = i + 1;
            }
        } else { //当总页数大于导航页码数时
            navigatepageNums = new int[navigatePages];
            int startNum = num - navigatePages / 2;
            int endNum = num + navigatePages / 2;
  
            if (startNum < 1) {
                startNum = 1;
                //(最前navigatePages页
                for (int i = 0; i < navigatePages; i++) {
                    navigatepageNums[i] = startNum++;
                }
            } else if (endNum > totalPages) {
                endNum = totalPages;
                //最后navigatePages页
                for (int i = navigatePages - 1; i >= 0; i--) {
                    navigatepageNums[i] = endNum--;
                }
            } else {
                //所有中间页
                for (int i = 0; i < navigatePages; i++) {
                    navigatepageNums[i] = startNum++;
                }
            }
        } 
        this.navigatepageNums = navigatepageNums;
    }

controller中传入需要的导航数:5页

    @GetMapping("/categories")
    public Page4Navigator<Category> list(@RequestParam(value = "start", defaultValue = "0") int start, @RequestParam(value = "size", defaultValue = "5") int size) throws Exception {
        start = start<0?0:start;
        Page4Navigator<Category> page =categoryService.list(start, size, 5);  //5表示导航分页最多有5个,像 [1,2,3,4,5] 这样
        return page;
    }

service中调用封装好的工具类 Page4Navigator

    public Page4Navigator<Category> list(int start, int size, int navigatePages) {
        Sort sort = new Sort(Sort.Direction.DESC, "id");
        Pageable pageable = new PageRequest(start, size,sort);
        Page pageFromJPA =categoryDAO.findAll(pageable);
 
        return new Page4Navigator<>(pageFromJPA,navigatePages);
    }

前端

思路:

  • 开始加载的时候访问uri,mounted:function()调用method中的list()方法,传入参数0;

  • paginationbeans得到数据,取出数据放到分页条中

  • 点击最前页时,传入参数firstjump(page,vue),调用下面的同名函数jump()中的list(0),调用vuelist(0)。相当于vue提供的三个方法中间夹带着方法。


构造出导航条

<div class="pageDiv" th:fragment="html">
    <nav>
      <ul class="pagination">
        <li :class="{ disabled: pagination.first }">
          <a  href="#nowhere" @click="jump('first')">«</a>
        </li>
        <li :class="{ disabled: !pagination.hasPrevious }">
          <a  href="#nowhere" @click="jump('pre')">‹</a>
        </li>           

        <li  v-for="i in pagination.navigatepageNums">
            <a href="#nowhere" @click="jumpByNumber(i-1)" >
                {{i}}
            </a>
        </li>

        <li :class="{ disabled: !pagination.hasNext }">
          <a  href="#nowhere" @click="jump('next')">›</a>
        </li>
        <li :class="{ disabled: pagination.last }">
          <a  href="#nowhere" @click="jump('last')">»</a>
        </li>           
      </ul>
    </nav>    
</div>
    $(function(){
        var data4Vue = {
            uri:'categories',
            pagination:{},
            beans: []
        };
 
        //ViewModel
        var vue = new Vue({
            el: '#workingArea',
            data: data4Vue,
            mounted:function(){ //mounted 表示这个 Vue 对象加载成功了
                this.list(0);
            },
            methods: {
                list:function(start){
                    var url =  this.uri+ "?start="+start;
                    axios.get(url).then(function(response) {
                        vue.pagination = response.data;
                        vue.beans = response.data.content   ;
                    });
                },
                jump: function(page){
                    jump(page,vue); //定义在adminHeader.html 中
                },
                jumpByNumber: function(start){
                    jumpByNumber(start,vue);
                }
            }
        });
    });

    //跳转函数
    function jump(page,vue){
        if('first'== page && !vue.pagination.first)
            vue.list(0);
        
        else if('pre'== page && vue.pagination.hasPrevious )
            vue.list(vue.pagination.number-1);
        
        else if('next'== page && vue.pagination.hasNext)
            vue.list(vue.pagination.number+1);                  
        
        else if('last'== page && !vue.pagination.last)
            vue.list(vue.pagination.totalPages-1);      
    }
    //跳转函数
    function jumpByNumber(start,vue){
        if(start!=vue.pagination.number)
            vue.list(start);        
    }

原文地址:https://www.cnblogs.com/senup/p/12171248.html