JSP + laypage分页完整案例

之前用过datatables进行过分页,尽管其功能非常完善,但是代码稍嫌复杂,样式不是很美观,不经意间发现了laypage分页插件,其对于不进行排序、模糊查询的分页代码书写非常人性化,特此记录。

1.效果图

2.html页面

district.html
<!DOCTYPE HTML>
<html>
<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>laypage 分页</title>
    <link rel="shortcut icon" href="favicon.ico" type="image/x-icon">
    <link rel="stylesheet" href="hui/static/layui/css/layui.css">
</head>

<body>
<div class="layui-container" style="margin-top: 50px">
    <table class="layui-table">
        <thead>
            <tr>
                <th>did</th>
                <th>dname</th>
                <th>cname</th>
                <th>pname</th>
                <th>postcode</th>
                <th>areacode</th>
                <th>orderid</th>
            </tr>
        </thead>
        <!--分页数据盛放器-->
        <tbody></tbody>
        <!---------------->
    </table>
    <!--分页容器-->
    <div id="page" style="text-align:right"></div>
    <!----------->
</div>

<script src="hui/js/jquery-3.3.1.min.js"></script>
<script src="hui/static/layui/layui.js"></script>
<script>
    let curr = 1;// 当前页,初始值设为 1
    let limit = 10;// 每页条数,初始值设为 10
    let total;// 总记录数

    $(document).ready(function () {
        getInfo();// 获取数据
        toPage();// 进行分页
    });

    // 获取数据
    function getInfo() {
        $.ajax({
            type: "post",
            url: "district",
            async: false,// 设置同步请求,加载数据前锁定浏览器
            dataType: 'json',
            data: {
                "curr": curr, // 查询页码
                "limit": limit, // 每页条数
            },
            success: successFu
        });
    }

    // 数据请求成功
    function successFu(pager) {
        //console.log(data);
        // 1.清空原数据
        $("tbody").html("");

        // 2.重新赋值页码、条数、总记录数
        curr = pager.start;
        limit = pager.limit;
        total = pager.total;

        // 3.渲染数据
        // 当前查询无数据时
        if (pager.total == 0) {
            $("tbody").html("<tr><td colspan='7' class='text-center'>暂无数据</td></tr>");
            return;
        }

        let text = "";
        $.each(pager.data, (i, item) => {
            text += `
            <tr>
                <th>${item.did}</th>
                <th>${item.dname}</th>
                <th>${item.cname}</th>
                <th>${item.pname}</th>
                <th>${item.postcode}</th>
                <th>${item.areacode}</th>
                <th>${item.orderid}</th>
            </tr>
             `;
        });
        $("tbody").html(text);
    }

    // 进行分页
    function toPage() {
        layui.use('laypage', function () {
            let laypage = layui.laypage;
            // 调用分页
            laypage.render({
                // 分页容器的id
                elem: 'page',// *必选参数
                // 数据总数,从服务端得到
                count: total,// *必选参数
                // 每页显示的条数。laypage将会借助 count 和 limit 计算出分页数。
                //limit:limit,
                // 起始页
                //curr:Pager,
                // 连续出现的页码个数
                //groups:5,
                // 自定义每页条数的选择项
                limits: [10, 25, 50, 100],
                // 自定义首页、尾页、上一页、下一页文本
                first: '首页',
                last: '尾页',
                prev: '<em><<</em>',
                next: '<em>>></em>',
                // 自定义主题
                theme: "#FF5722",
                // 自定义排版
                layout: ['count', 'prev', 'page', 'next', 'limit', 'skip'],
                // 渲染数据
                jump: function (data, first) {
                    // data包含了当前分页的所有参数
                    curr = data.curr;
                    limit = data.limit;

                    // 首次不执行
                    if (!first) {
                        getInfo();
                    }
                }
            });
        })
    }
</script>
</body>
</html>

3.servlet页面

DistrictServlet.java
package com.XXX.servlet;

import com.XXX.dao.DistrictViewDao;
import com.XXX.pager.Pager;
import com.XXX.pojo.DistrictView;
import net.sf.json.JSON;
import net.sf.json.JSONSerializer;
import org.apache.commons.lang.math.NumberUtils;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;

@WebServlet(name = "${Entity_Name}", urlPatterns = "/${Entity_Name}")
public class DistrictServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //request.setCharacterEncoding("utf-8");
        response.setContentType("application/json;charset=utf-8");

        System.out.println("开始查询数据...");
        // 1.获得页面数据
        Integer curr = NumberUtils.createInteger(request.getParameter("curr"));// 当前页
        Integer limit = NumberUtils.createInteger(request.getParameter("limit"));// 条数

        DistrictViewDao dao = new DistrictViewDao();
        // 2.查询数据库
        // 2.1 查询总记录数
        int total = dao.getTotal();
        // 2.2 查询分页数据
        List<DistrictView> data = dao.find(curr,limit);

        Pager<DistrictView> pager = new Pager<DistrictView>();
        // 3.封装分页类对象
        pager.setCurr(curr);
        pager.setLimit(limit);
        pager.setTotal(total);
        pager.setData(data);

        // 4.转换为json格式数据
        JSON json = JSONSerializer.toJSON(pager);

        PrintWriter out = response.getWriter();
        // 4.响应给客户端
        out.println(json.toString());

        out.flush();
        out.close();
    }
}

4.dao层

DistrictViewDao.java
package com.XXX.dao;

import com.XXX.pojo.DistrictView;
import org.apache.ibatis.session.SqlSession;

import java.util.List;

public class DistrictViewDao {
    /**
     * 获得总记录数
     *
     * @return 总记录数
     */
    public int getTotal(){
        int total = 0;
        SqlSession sqlSession = null;
        try {
            sqlSession = MybatisSessionFactory.getSessionFactory().openSession();
            DistrictViewMapper mapper = sqlSession.getMapper(DistrictViewMapper.class);
            total = mapper.getTotal();
        } finally {
            sqlSession.close();
        }
        return total;
    }

    /**
     * 查询分页数据
     *
     * @param start 查询页码
     * @param limit 每页记录数
     * @return 分页数据
     */
    public List<DistrictView> find(int start,int limit){
        List<DistrictView> list = null;
        SqlSession sqlSession = null;
        try {
            sqlSession = MybatisSessionFactory.getSessionFactory().openSession();
            DistrictViewMapper mapper = sqlSession.getMapper(DistrictViewMapper.class);
            start = (start-1)*limit;
            list = mapper.find(start,limit);
        } finally {
            sqlSession.close();
        }
        return list;
    }
}

5.其他

Pager.java
package com.XXX.pager;

import java.util.List;

/**
 * 分页封装类
 *
 * @param <T>
 */
public class Pager<T> {
    // 当前页
    private Integer curr;
    // 每页条数
    private Integer limit;
    // 总记录数
    private Integer total;
    // 分页数据
    List<T> data;

    public Pager() {
    }

    // getter/setter....
}
DistrictView.java
package com.XXX.pojo;

/**
 * 区县表视图类
 */
public class DistrictView {
    //did	dname	cname	pname	postcode	areacode	orderid
    private Integer did;
    private String dname;
    private String cname;
    private String pname;
    private String postcode;
    private String areacode;
    private Integer orderid;

    public DistrictView() {
    }

    // getter/setter....
}


2019-01-28 补充更新

入行一年多,再回过来看以前的代码,有点感慨,自认为当时学习还是比较刻苦,现在看来写的代码还是很多问题。这次整理博客,本想着删掉原稿修改后重新发布,再想想,还是留个记录吧,说不定哪天就写不动代码了,做个念想。

layui中的分页组件,仔细看了API,发现还是比较适合做前端分页,做后端分页的话就涉及到了一个异步渲染的问题,在此之前我是采用的async:false这个取巧的方式来锁定浏览器以达到先拿到数据再渲染分页功能的效果,实际开发中,这是行不通的,锁定该请求在一定程度上就会阻塞其他请求,导致浏览器渲染效率的降低,在此根据ES6的Promise函数对原稿进行重写。

(1)服务器分页

db-pager-demo.html
<!DOCTYPE HTML>
<html>
<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>laypage 服务器分页</title>
    <link rel="shortcut icon" href="favicon.ico" type="image/x-icon">
    <link rel="stylesheet" href="hui/static/layui/css/layui.css">
</head>

<body>
<div class="layui-container" style="margin-top: 50px">
    <table class="layui-table">
        <thead>
        <tr>
            <th>did</th>
            <th>dname</th>
            <th>cname</th>
            <th>pname</th>
            <th>postcode</th>
            <th>areacode</th>
            <th>orderid</th>
        </tr>
        </thead>
        <!--分页数据盛放器-->
        <tbody></tbody>
        <!---------------->
    </table>
    <!--分页容器-->
    <div id="page" style="text-align:right"></div>
    <!----------->
</div>

<script src="hui/js/jquery-3.3.1.min.js"></script>
<script src="hui/static/layui/layui.js"></script>
<script>
    window.onload = () => {
        requestFn({currentPage: 1, pageSize: 10}).then(({total = 0, data = []} = {}) => {
            /* 执行分页 */
            layui.use('laypage', () => {
                const laypage = layui.laypage;
                // 调用分页
                laypage.render({
                    // 分页容器的id
                    elem: 'page',// *必选参数
                    // 数据总数,从服务端得到
                    count: total,// *必选参数
                    // 起始页
                    curr: 1,
                    // 连续出现的页码个数
                    groups: 5,
                    // 自定义每页条数的选择项
                    limits: [10, 25, 50, 100],
                    // 自定义首页、尾页、上一页、下一页文本
                    first: '首页',
                    last: '尾页',
                    prev: '<em>&lt;&lt;</em>',
                    next: '<em>&gt;&gt;</em>',
                    // 自定义主题
                    theme: "#FF5722",
                    // 自定义排版
                    layout: ['count', 'prev', 'page', 'next', 'limit', 'skip'],
                    // 渲染数据
                    jump: (obj, first) => {  // obj包含了当前分页的所有参数
                        // 首次不执行
                        if (!first) requestFn({currentPage: obj.curr, pageSize: obj.limit});
                    }
                });
            })
        })
    };

    /* 请求数据 */
    function requestFn(params) {
        return new Promise((reslove, reject) => {
            $.ajax({
                type: "post",
                url: "addressServlet",
                dataType: 'json',
                data: params,
                success: (data) => {
                    renderData(data);
                    reslove(data);
                }
            });
        })
    }

    /* 渲染数据 */
    function renderData({total = 0, data = []} = {}) {
        const $tbody = $("tbody");
        // 1.清空原数据
        $tbody.html("");
        // 2.渲染数据
        // 2.1 当前查询无数据时
        if (total === 0) {
            $tbody.html("<tr><td colspan='7' class='text-center'>暂无数据</td></tr>");
            return;
        }
        // 2.2 当前查询数据存在时
        let text = ``;
        data.forEach(item => {
            text += `
                        <tr>
                            <th>${item.did}</th>
                            <th>${item.dname}</th>
                            <th>${item.cname}</th>
                            <th>${item.pname}</th>
                            <th>${item.postcode}</th>
                            <th>${item.areacode}</th>
                            <th>${item.orderid}</th>
                        </tr>
                        `
        });
        $tbody.html(text);
    }
</script>
</body>
</html>

(2)前端分页

web-pager-demo.html
<!DOCTYPE HTML>
<html>
<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>laypage 前端分页</title>
    <link rel="shortcut icon" href="favicon.ico" type="image/x-icon">
    <link rel="stylesheet" href="hui/static/layui/css/layui.css">
</head>

<body>
<div class="layui-container" style="margin-top: 50px">
    <table class="layui-table">
        <thead>
        <tr>
            <th>did</th>
            <th>dname</th>
            <th>cname</th>
            <th>pname</th>
            <th>postcode</th>
            <th>areacode</th>
            <th>orderid</th>
        </tr>
        </thead>
        <!--分页数据盛放器-->
        <tbody></tbody>
        <!---------------->
    </table>
    <!--分页容器-->
    <div id="page" style="text-align:right"></div>
    <!----------->
</div>

<script src="hui/js/jquery-3.3.1.min.js"></script>
<script src="hui/static/layui/layui.js"></script>
<script>
    window.onload = () => {
        requestFn();
    };

    /* 请求数据 */
    function requestFn() {
        $.ajax({
            type: "get",
            url: "addressServlet",
            dataType: 'json',
            success: ({total = 0, data = []} = {}) => {
                // 调用分页
                layui.use('laypage', () => {
                    const laypage = layui.laypage;

                    laypage.render({
                        elem: 'page',
                        count: data.length,
                        jump: function (obj) {
                            //模拟渲染
                            document.querySelector('tbody').innerHTML = function () {
                                let arr = [],
                                    thisData = data.concat().splice(obj.curr * obj.limit - obj.limit, obj.limit);
                                layui.each(thisData, function (index, item) {
                                    let text = `
                                    <tr>
                                        <th>${item.did}</th>
                                        <th>${item.dname}</th>
                                        <th>${item.cname}</th>
                                        <th>${item.pname}</th>
                                        <th>${item.postcode}</th>
                                        <th>${item.areacode}</th>
                                        <th>${item.orderid}</th>
                                    </tr>
                                `;
                                    arr.push(text);
                                });
                                return arr.join('');
                            }();
                        }
                    });
                })
            }
        });
    };
</script>
</body>
</html>

PS:有兴趣的朋友可以考虑下载新修demo完整代码,附上结构图及链接:

https://download.csdn.net/download/zhengvipin/10942565

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 9
    评论
JSP和Servlet中进行分页查询的主要步骤如下: 1. 在JSP页面中,使用<a>标签创建一个链接到Servlet的URL。该链接将包含一个参数,用于指示要查询的页码。例如,可以使用以下代码创建一个链接到Servlet的URL: ```html <a href="<%= request.getContextPath() %>/action?page=<%= page + 1 %>">下一页</a> ``` 这里的`page`是一个变量,表示当前页码。 2. 在Servlet中,使用HttpServletRequest的getParameter方法获取请求中的参数值。例如,可以使用以下代码获取名为"page"的参数的值: ```java int page = Integer.parseInt(request.getParameter("page")); ``` 3. 在Servlet中,根据获取到的页码参数,进行相应的查询操作,获取需要显示的数据。 4. 将查询结果存储在适当的作用域对象中,例如使用request.setAttribute方法将查询结果存储在request对象中,以便在JSP页面中使用。 5. 在JSP页面中,使用EL表达式或JSTL标签库来显示查询结果。 需要注意的是,以上代码只是一个基本的示例,实际的实现可能会根据具体需求有所不同。另外,还可以考虑添加一些验证和错误处理的逻辑,以确保分页查询的正确性和稳定性。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [使用Servlet和JSP完成分页查询](https://blog.csdn.net/qq_33036061/article/details/83753789)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zhengvipin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值