SpringBoot带省略号的翻页实现(不使用带三方插件)方案一(转载)

转载地址:https://liuyanzhao.com/8125.html

方案二传送阵:https://blog.csdn.net/thankna/article/details/105600475 (方案一简化版)

方案三传送阵:https://blog.csdn.net/thankna/article/details/105933927(方案二基础上支持复杂sql文)

最近工作中用到,网上查资料,大部分都是代码片段,对前后台接口描述不详,不方便照方抓药。

下面这篇是我花了2天时间,在网上最完整的,我参照这个方案写了自己的代码,后面会放出方案二(是我自己写的代码)。

!!!注意:转载这篇使用SpringBoot1.X,Spring Boot 2.0之后已经废弃new PageRequest()方法,换用静态方法PageRequest.of(pageNum,pageSize,Sort.Direction…..)。


SpringBoot + Spring Data JPA + Thmeleaf 分页

效果图
标题

一、Controller

/**
    * ajax 获取评论页面数据
    *
    * @param postId
    * @param model
    * @return
    */
   @GetMapping
   public ModelAndView listComments(
           @RequestParam(value = "postId") Long postId,
           @RequestParam(value = "async", required = false, defaultValue = "new") Boolean async,
           @RequestParam(value = "order", required = false, defaultValue = "new") String order,
           @RequestParam(value = "pageIndex", required = false, defaultValue = "1") Integer pageIndex,
           @RequestParam(value = "pageSize", required = false, defaultValue = "1") Integer pageSize,
           Model model) {
       Page<Comment> commentPage = null;
       Post post = postService.getPostById(postId);
       String commentOrder = "new";
       try {
           if (order.equals("hot")) { // 最热查询
               Sort sort = new Sort(Sort.Direction.DESC, "zanSize", "id");  //根据点赞数量排序
               Pageable pageable = new PageRequest(pageIndex - 1, pageSize, sort);
               commentPage = commentService.listCommentByPost(post, pageable);
               commentOrder = "hot";
           } else if (order.equals("new")) { // 最新查询
               Sort sort = new Sort(Sort.Direction.DESC, "id");
               Pageable pageable = new PageRequest(pageIndex - 1, pageSize, sort);
               commentPage = commentService.listCommentByPost(post, pageable);
           }
       } catch (Exception e) {
           Pageable pageable = new PageRequest(0, 10);
           commentPage = commentService.listCommentByPost(post, pageable);
       }
       Integer commentSize = post.getCommentSize();
       model.addAttribute("page", commentPage);
       model.addAttribute("commentSize", commentSize);
       model.addAttribute("commentOrder", commentOrder);
       model.addAttribute("post", post);
       return new ModelAndView(async == true ? "home/post_detail :: #comment" : "home/post_detail");
   }

二、HTML 代码

1、post_detail.html

本项目使用了 Spring Security ,开启了 CSRF 防护,所以需要在 head 里引入

<meta name="_csrf" th:content="${_csrf.token}"/>
<meta name="_csrf_header" th:content="${_csrf.headerName}"/>

这是 Thymeleaf 的替换标签

<!--分页-->
<div th:replace="~{home/fragments/page :: header-page}"></div>
<!--/分页-->

页面底部,引入 JS,将文章的id postId 传到 js 里

<script th:inline="javascript">
    var postId = [[${post.id}]];
    var postUrl = '/' + [[${post.user.username}]] + '/posts/' + [[${post.id}]];
</script>

page.html

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>分页</title>
</head>
<body>
<div data-th-fragment="header-page">
    <div class="header-page paging-box"
         th:if="${(page.totalPages gt 0) && (page.totalPages le 7)}"
         data-th-attr="data-order=${commentOrder}">
        <span class="result">共[[${page.totalPages}]]页</span>
        <a href="javascript:void(0)" class="page-link prev"
           th:classappend="${page.first?'disabled':''}"
           data-th-attr="pageIndex=${page.number}">上一页</a>
        <a href="javascript:void(0)" class="page-link"
           th:classappend="${(page.number+1) eq i} ?'current':''"
           th:each="i: ${#numbers.sequence(1, page.totalPages)}"
           data-th-attr="pageIndex=${i}">[[${i}]]</a>
        <a href="javascript:void(0)" class="page-link next"
           th:classappend="${page.last?'disabled':''}"
           data-th-attr="pageIndex=${page.number+2}">下一页</a>
    </div>
    <div class="header-page paging-box"
         th:if="${page.totalPages gt 7}"
         data-th-attr="data-order=${commentOrder}">
        <span class="result">共[[${page.totalPages}]]页</span>
        <!--上一页-->
        <a href="javascript:void(0)" class="page-link prev"
           th:classappend="${page.first?'disabled':''}"
           data-th-attr="pageIndex=${page.number}">上一页</a>
        <!--首页-->
        <a href="javascript:void(0)" class="page-link"
           th:classappend="${(page.number+1) eq 1} ?'current':''"
           data-th-attr="pageIndex=1">
            1
        </a>
        <!-- 当前页面小于等于4 -->
        <a href="javascript:void(0)" class="page-link"
           th:if="${(page.number+1) le 4}"
           th:classappend="${(page.number+1) eq i} ?'current':''"
           data-th-each="i : ${#numbers.sequence(2,5)}"
           data-th-attr="pageIndex=${i}">[[${i}]]</a>
        <span class="dian" data-th-if="${(page.number + 1) le 4}">...</span>
        <!-- 最后一页与当前页面之差,小于等于3 -->
        <span class="dian"
              data-th-if="${(page.totalPages-(page.number + 1)) le 3}">...</span>
        <a href="javascript:void(0)" class="page-link"
           th:if="${(page.totalPages-(page.number + 1)) le 3}"
           th:classappend="${(page.number+1) eq i} ?'current':''"
           th:each="i : ${#numbers.sequence(page.totalPages-4, page.totalPages-1)}"
           data-th-attr="pageIndex=${i}">[[${i}]]</a>
        <!-- 最后一页与当前页面之差大于3,且当前页面大于4-->
        <span class="dian"
              data-th-if="${((page.number + 1) gt 4) && ((page.totalPages-(page.number + 1)) gt 3 )}">...</span>
        <a href="javascript:void(0)" class="page-link"
           th:if="${((page.number + 1) gt 4) && ((page.totalPages-(page.number + 1)) gt 3 )}"
           data-th-attr="pageIndex=${page.number}">[[${page.number}]]</a>
        <a href="javascript:void(0)" class="page-link current"
           th:if="${((page.number + 1) gt 4) && ((page.totalPages-(page.number + 1)) gt 3 )}"
           data-th-attr="pageIndex=${page.number+1}">[[${page.number
            +1 }]]</a>
        <a href="javascript:void(0)" class="page-link"
           th:if="${((page.number + 1) gt 4) && ((page.totalPages-(page.number + 1)) gt 3 )}"
           data-th-attr="pageIndex=${page.number+2}">[[${page.number
            +2 }]]</a>
        <span class="dian" data-th-if="${((page.number + 1) gt 4) && ((page.totalPages-(page.number + 1)) gt 3 )}">...</span>
        <!--尾页-->
        <a href="javascript:void(0)" class="page-link"
           th:classappend="${(page.number+1) eq page.totalPages} ?'current':''"
           data-th-attr="pageIndex=${page.totalPages}">
            [[${page.totalPages}]]
        </a>
        <!--下一页-->
        <a href="javascript:void(0)" class="page-link next"
           th:classappend="${page.last?'disabled':''}"
           data-th-attr="pageIndex=${page.number+2}">下一页</a>
    </div>
</div>
<div data-th-fragment="bottom-page">
    <div class="bottom-page paging-box-big" th:if="${(page.totalPages gt 0) && (page.totalPages le 7)}"
         data-th-attr="data-order=${commentOrder}">
        <a href="javascript:void(0)" class="page-link prev"
           th:classappend="${page.first?'disabled':''}"
           data-th-attr="pageIndex=${page.number}">上一页</a>
        <a href="javascript:void(0)" class="page-link"
           th:classappend="${(page.number+1) eq i} ?'current':''"
           th:each="i: ${#numbers.sequence(1, page.totalPages)}"
           data-th-attr="pageIndex=${i}">[[${i}]]</a>
        <a href="javascript:void(0)" class="page-link next"
           th:classappend="${page.last?'disabled':''}"
           data-th-attr="pageIndex=${page.number+2}">下一页</a>
        <div class="page-jump">共<span>[[${page.totalPages}]]</span>页,跳至
            <input type="number" class="jump-page-size" th:max="${page.totalPages}">页
        </div>
    </div>
    <div class="bottom-page paging-box-big"
         th:if="${page.totalPages gt 7}"
         data-th-attr="data-order=${commentOrder}">
        <!--上一页-->
        <a href="javascript:void(0)" class="page-link prev"
           th:classappend="${page.first?'disabled':''}"
           data-th-attr="pageIndex=${page.number}">上一页</a>
        <!--首页-->
        <a href="javascript:void(0)" class="page-link"
           th:classappend="${(page.number+1) eq 1} ?'current':''"
           data-th-attr="pageIndex=1">
            1
        </a>
        <!-- 当前页面小于等于4 -->
        <a href="javascript:void(0)" class="page-link"
           th:if="${(page.number+1) le 4}"
           th:classappend="${(page.number+1) eq i} ?'current':''"
           data-th-each="i : ${#numbers.sequence(2,5)}"
           data-th-attr="pageIndex=${i}">[[${i}]]</a>
        <span class="dian" data-th-if="${(page.number + 1) le 4}">...</span>
        <!-- 最后一页与当前页面之差,小于等于3 -->
        <span class="dian"
              data-th-if="${(page.totalPages-(page.number + 1)) le 3}">...</span>
        <a href="javascript:void(0)" class="page-link"
           th:if="${(page.totalPages-(page.number + 1)) le 3}"
           th:classappend="${(page.number+1) eq i} ?'current':''"
           th:each="i : ${#numbers.sequence(page.totalPages-4, page.totalPages-1)}"
           data-th-attr="pageIndex=${i}">[[${i}]]</a>
        <!-- 最后一页与当前页面之差大于3,且当前页面大于4-->
        <span class="dian"
              data-th-if="${((page.number + 1) gt 4) && ((page.totalPages-(page.number + 1)) gt 3 )}">...</span>
        <a href="javascript:void(0)" class="page-link"
           th:if="${((page.number + 1) gt 4) && ((page.totalPages-(page.number + 1)) gt 3 )}"
           data-th-attr="pageIndex=${page.number}">[[${page.number}]]</a>
        <a href="javascript:void(0)" class="page-link current"
           th:if="${((page.number + 1) gt 4) && ((page.totalPages-(page.number + 1)) gt 3 )}"
           data-th-attr="pageIndex=${page.number+1}">[[${page.number
            +1 }]]</a>
        <a href="javascript:void(0)" class="page-link"
           th:if="${((page.number + 1) gt 4) && ((page.totalPages-(page.number + 1)) gt 3 )}"
           data-th-attr="pageIndex=${page.number+2}">[[${page.number
            +2 }]]</a>
        <span class="dian" data-th-if="${((page.number + 1) gt 4) && ((page.totalPages-(page.number + 1)) gt 3 )}">...</span>
        <!--尾页-->
        <a href="javascript:void(0)" class="page-link"
           th:classappend="${(page.number+1) eq page.totalPages} ?'current':''"
           data-th-attr="pageIndex=${page.totalPages}">
            [[${page.totalPages}]]
        </a>
        <!--下一页-->
        <a href="javascript:void(0)" class="page-link next"
           th:classappend="${page.last?'disabled':''}"
           data-th-attr="pageIndex=${page.number+2}">下一页</a>
        <div class="page-jump">共<span>[[${page.totalPages}]]</span>页,跳至
            <input type="number" name="pageIndex" class="jump-page-size" min="1" th:max="${page.totalPages}">页
        </div>
    </div>
    <script>
        var pageIndex = [[${page.number+1}]]
    </script>
</div>
</body>
</html>

因为很多页面都要使用分页,所以完全可以把分页的代码剥离出来,公共使用。只需要将分页的数据的 model 写成 page 就行。这里分页分成了两种,一种是分页少于等于7个的,我们直接显示 1234567;另一种是大于7 的,则中间以..分隔。

三、JS 代码

$(function () {
    // 获取评论列表
    function getComment(postId, pageIndex, order) {
        var _ctx = $("meta[name='ctx']").attr("content");
        // 获取 CSRF Token
        var token = $("meta[name='_csrf']").attr("content");
        var header = $("meta[name='_csrf_header']").attr("content");
        $.ajax({
            url: _ctx + '/comments',
            type: 'GET',
            data: {
                "async": true,
                "postId": postId,
                "pageIndex": pageIndex,
                "order": order
            },
            beforeSend: function (request) {
                request.setRequestHeader(header, token); // 添加  CSRF Token
            },
            success: function (data) {
                $("#comment-wrapper").html(data);
            },
            error: function () {
                layer.msg("出现错误,请尝试刷新页面!", {icon: 2, anim: 6});
            }
        });
    };
    //切换评论排序规则
    $(document).on('click', '.tabs-order .new-sort', function () {
        var pageIndex = $(this).attr("pageIndex");
        getComment(postId, pageIndex, "new");
    });
    $(document).on('click', '.tabs-order .hot-sort', function () {
        var pageIndex = $(this).attr("pageIndex");
        getComment(postId, pageIndex, "hot");
    });
    //分页获取评论列表
    $(document).on('click', '.tcd-number', function () {
        var order = $(this).parents(".paging-box").attr("data-order");
        if ($(this).hasClass('current')) {
            return false;
        }
        var pageIndex = $(this).attr("pageIndex");
        getComment(postId, pageIndex, order);
    });
    //跳转到指定的页号
    $(document).on('keydown', '.jump-page-size', function (event) {
        var max = parseInt($(this).attr("max"));
        var pageIndex = parseInt($(this).val());
        var order = $('.paging-box').attr('data-order');
        if (event.keyCode == "13") {//keyCode=13是回车键
            if (pageIndex == "" || pageIndex == null) {
                return false;
            }
            if (!/^\d+$/.test(pageIndex)) {
                pageIndex = 1;
            }
            if (pageIndex < 1) {
                pageIndex = 1;
            }
            if (pageIndex > max) {
                pageIndex = max;
            }
            getComment(postId, pageIndex, order);
        }
    })
// 初始化 博客评论列表
    getComment(postId, 1, "new");
})

四、CSS 代码

为了方便大家的使用,这里同时提供 CSS 代码。

注:本模板是扒自哔哩哔哩,侵删

page.css

.paging-box {
    font-size: 12px
}
.paging-box .disabled {
    cursor: not-allowed
}
.paging-box .current, .paging-box .dian, .paging-box .next, .paging-box .prev, .paging-box .tcd-number {
    color: #222;
    cursor: pointer;
    text-align: center;
    margin: 0 4px;
    text-decoration: none;
    line-height: 26px
}
.paging-box .current:hover, .paging-box .dian:hover, .paging-box .next:hover, .paging-box .prev:hover, .paging-box .tcd-number:hover {
    color: #00a1d6
}
.paging-box .current {
    color: #00a1d6;
    font-weight: 700
}
.paging-box .dian {
    cursor: default
}
.paging-box .dian:hover {
    color: #222
}
.paging-box .result {
    padding-right: 10px
}
.paging-box-big {
    font-size: 12px
}
.paging-box-big .disabled {
    display: none
}
.paging-box-big .current, .paging-box-big .dian, .paging-box-big .next, .paging-box-big .prev, .paging-box-big .tcd-number {
    color: #222;
    cursor: pointer;
    text-align: center;
    border-radius: 4px;
    background-color: #fff;
    border: 1px solid #ddd;
    background-image: none;
    transition: all .2s;
    font-size: 14px;
    min-width: 15px;
    margin: 0 2px;
    padding: 0 13px;
    display: inline-block;
    height: 36px;
    line-height: 36px;
    text-decoration: none
}
.paging-box-big .current, .paging-box-big .current:hover, .paging-box-big .dian:hover, .paging-box-big .next:hover, .paging-box-big .prev:hover, .paging-box-big .tcd-number:hover {
    background: #00a1d6;
    color: #fff;
    border: 1px solid #00a1d6
}
.paging-box-big .dian {
    cursor: default;
    border-color: #fff
}
.paging-box-big .dian:hover {
    background: #fff;
    color: #222;
    border: 1px solid #fff
}
.paging-box-big .next, .paging-box-big .prev {
    padding: 0 15px
}
.paging-box-big .page-jump {
    float: rightright;
    color: #99a2aa;
    line-height: 36px
}
.paging-box-big .page-jump input {
    margin: 0 5px;
    padding: 0 2px;
    height: 24px;
    line-height: 24px;
    margin-top: 7px;
    font-size: 12px;
    box-shadow: none;
    width: 40px;
    border-radius: 4px;
    border: 1px solid #ddd;
    outline: 0;
    text-align: center
}
.paging-box-big .page-jump input:focus {
    border-color: #00a1d6
}

五、补充

1、Spring Data JPA 提供了分页器,可以直接使用。

/**
 * 根据文章获取评论,分页显示
 *
 * @param post
 * @param pid
 * @return
 */
Page<Comment> findByPostAndPid(Post post, Long pid, Pageable pageable);

其中 pageable 可以通过创建 PageRequest 对象获得,需要传入 page 页码,size 一页显示数量。sort 是排序规则,相当于 sql 语句里的 order by,可选。

Sort sort = new Sort(Sort.Direction.DESC, "zanSize", "id");
Pageable pageable = new PageRequest(pageIndex - 1, pageSize, sort);

2、将现成 List 转成 Page,也可以这样

List<Comment> commentList = post.getCommentList()
PageRequest pageRequest = new PageRequest(pageIndex,pageSize);
Page<Comment> commentPage = new PageImpl<Comment>(commentList,pageRequest,commentList.size());

3、page 对象的几个属性

总共页数:${userDTOPage.totalPages}
记录总数:${userDTOPage.totalElements}
当前页号:${userDTOPage.number}
是否为首页:${userDTOPage.first}
是否为尾页:${userDTOPage.last}
每页显示的数量:${userDTOPage.numberOfElements}

END


这篇没有GitHub代码。代码都在文案上,大家自己复制吧。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值