servlet+mvc实现分页显示列表页

实现分页显示有好多种方法,有客户端显示的用JS,有服务端分页的。在此我对服务端的分页功能进行叙述
先展示下我的项目的目录结构:
目录结构
标准的MVC模式,现在我的分页步骤是从jsp调用servlet,通过servlet调用对应的service类,service类去调用dao类
1、先看下页面中的调用方式:

<div>当前${requestScope.pageBean.currentPage}/${requestScope.pageBean.totalPage }页
    <a href="${pageContext.request.contextPath}/SenInfoManagerServlet?method=showSenInfo&currentPage=1">首页</a>
    <a href="${pageContext.request.contextPath }/SenInfoManagerServlet?method=showSenInfo&currentPage=${requestScope.pageBean.currentPage-1}">上一页</a>
    <a href="${pageContext.request.contextPath }/SenInfoManagerServlet?method=showSenInfo&currentPage=${requestScope.pageBean.currentPage+1}">下一页</a>
    <a href="${pageContext.request.contextPath }/SenInfoManagerServlet?method=showSenInfo&currentPage=${requestScope.pageBean.totalPage}">尾页</a>
    </div>

定义了当前页,首页,上一页,下一页,尾页等方式。通过调用对应的servlet及currentPage,totalPage等参数,传递对应的pageBean数据
2、再看下servlet调用时的代码:

private void showSenInfo(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException{

        try {
            String currPage = request.getParameter("currentPage");
            if(currPage == null || "".equals(currPage.trim())) {
                currPage = "1"; //第一次访问,设置当前页为1
            }
            int currentPage = Integer.parseInt(currPage);
            PageBean<SenInfo> pageBean = new PageBean<SenInfo>();
            pageBean.setCurrentPage(currentPage);

            List<SenInfo> pageData = senInfoService.getAllSenInfo(pageBean);
            request.setAttribute("senInfoList",pageData);
            request.setAttribute("pageBean", pageBean);

            uri = request.getRequestDispatcher("/manager/senInfoManager.jsp");
            WebUtils.goTo(request,response,uri);
        }catch(Exception e) {
            LogUtils.getLogger(SenInfoManagerServlet.class.getName(), "error", e.toString());
        }
    }

此方法获取当前页参数,其中对应的PageBean类是我定义的翻页的Model类,下面看PageBean对应的设计代码:

public class PageBean<T> {

    private int currentPage = 1; //当前页,默认显示第一页
    private int pageCount = 10; //每页显示的行数(查询返回的行数)
    private int totalCount;  //总记录数
    private int totalPage;  //总页数= 总记录数/每页显示的行数(+1)
    private List<T> pageData; // 分页查询到的数据

    public int getCurrentPage() {
        return currentPage;
    }
    public void setCurrentPage(int currentPage) {
        this.currentPage = currentPage;
    }
    public int getPageCount() {
        return pageCount;
    }
    public void setPageCount(int pageCount) {
        this.pageCount = pageCount;
    }
    public int getTotalCount() {
        return totalCount;
    }
    public void setTotalCount(int totalCount) {
        this.totalCount = totalCount;
    }
    public int getTotalPage() {
        if(totalCount % pageCount == 0) {
            totalPage = totalCount / pageCount;
        }else {
            totalPage = totalCount / pageCount +1;
        }
        return totalPage;
    }
    public void setTotalPage(int totalPage) {
        this.totalPage = totalPage;
    }
    public List<T> getPageData() {
        return pageData;
    }
    public void setPageData(List<T> pageData) {
        this.pageData = pageData;
    }

}

在此分页类中设置了当前页currentPage,每页显示的总行数pageCount,总记录数totalCount,分页查询到的数据列表。
3、通过service调用dao类不再展示,其中service类没做其他任何操作,直接调用的dao类,现在看看dao类的设计代码:
先获取总数目:

/**
     * 获取总数目
     */
    @Override
    public int getTotalCount() {
        StringBuilder sb = new StringBuilder();
        sb.append(" SELECT");
        sb.append(" count(*) ");
        sb.append(" FROM ");
        sb.append(" senInfo");
        try {
            Long count = qr.query(sb.toString(), new 
                    ScalarHandler<Long>());
            return count.intValue();
        }catch(Exception e) {
            LogUtils.getLogger(SenInfoDao.class.getName(), "error", e.toString());
        }
        return 0;
    }

再获取每页对应的数据:

QueryRunner qr = DBUtils.getQueryRunner();

    @Override
    public List<SenInfo> getAllSenInfo(PageBean<SenInfo> pageBean) {
        int totalCount = this.getTotalCount();
        pageBean.setTotalCount(totalCount);

        if(pageBean.getCurrentPage() <= 0) {
            pageBean.setCurrentPage(1);
        }else if(pageBean.getCurrentPage() > pageBean.getTotalPage()) {
            pageBean.setCurrentPage(pageBean.getTotalPage());
        }
        //获取当前页:计算查询的起始行,返回的行数
        int currentPage = pageBean.getCurrentPage();
        int index = (currentPage - 1) * pageBean.getPageCount(); //查询起始行
        int count = pageBean.getPageCount(); //每页显示的行数

        List<Object> list = new ArrayList<Object>();
        StringBuilder sb = new StringBuilder();
        sb.append(" SELECT");
        sb.append(" *");
        sb.append(" FROM ");
        sb.append(" senInfo ");
        sb.append(" limit ?,? ");
        list.add(index);
        list.add(count);
        List<SenInfo> pageData = null;

        try {
            //根据当前页,查询当前页数据(一页数据)
            if(index >= 0) {

                pageData = qr.query(sb.toString(), new BeanListHandler<SenInfo>(SenInfo.class),list.toArray());
                pageBean.setPageData(pageData);
                System.out.println("数据:"+pageData.toString());
            }
        }catch(Exception e) {
            LogUtils.getLogger(SenInfoDao.class.getName(), "error", e.toString());
        }
        return pageData;
    }

其中的实质内容在于mysql的语句,mysql分页语句如下:
Select * from 表名 limit startrow,pagesize
(Pagesize为每页显示的记录条数)
附:数据库分页查询语句:

1.oracle数据库分页
    select * from (select a.*,rownum rc from 表名 where rownum<=endrow) a where a.rc>=startrow

2.DB2数据库分页
    Select * from (select rownumber() over() as rc,a.* from (select * from 表名 order by列名) as a) where rc between startrow and endrow

3.SQL Server 2000数据库分页
    Select top pagesize * from 表名 where 列名 not in(select top pagesize*page 列名 from 表名 order by列名) order by列名

4.SQL Server 2005数据库分页
    Select * from (select 列名,row_number() over(order by 列名1) as 别名from 表名) as t where t.列名1>=startrow and t.列名1<=endrow

5.MySQL数据库分页
    Select * from 表名 limit startrow,pagesize
    (Pagesize为每页显示的记录条数)

6.PostgreSQL数据库分页
    Select * from 表名 limit pagesize,offset startrow
    (Pagesize为每页显示的记录条数)

总结:上述标准展示了MVC的调用方法,具体代码就不再过多显示。
代码有何不懂,可以跟帖回问。仅供参考!

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
/* * @(#)PageControl.java 1.00 2004-9-22 * * Copyright 2004 2004 . All rights reserved. * PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */ package com.hexiang.utils; /** * PageControl, 分页控制, 可以判断总数和是否有上下. * * 2008-07-22 加入输出上下分页HTML代码功能 * * @author HX * @version 1.1 2008-9-22 */ public class PageBean { /** 每显示记录数 */ private int pageCount; /** 是否有上一 */ private boolean hasPrevPage; /** 记录总数 */ private int recordCount; /** 是否有下一 */ private boolean hasNextPage; /**总面数 */ private int totalPage; /** 当前码数 */ private int currentPage; /** * 分页前的面地址 */ private String pageUrl; /** * 输出分页 HTML 面跳转代码, 分链接和静态文字两种. * 2008-07-22 * @return HTML 代码 */ public String getPageJumpLinkHtml() { if(StringUtil.isEmpty(pageUrl)) { return ""; } // 检查是否有参数符号, 没有就加上一个? if(pageUrl.indexOf('?') == -1) { pageUrl = pageUrl + '?'; } StringBuffer buff = new StringBuffer("<span id='pageText'>"); // 上一标记 if(currentPage > 1) { buff.append("[ <a href='" + pageUrl + "&page=" + (currentPage - 1) + "' title='转到第 " + (currentPage - 1) + " '>上一</a> ] "); } else { buff.append("[ 上一 ] "); } // 下一标记 if(currentPage < getTotalPage()) { buff.append("[ <a href='" + pageUrl + "&page=" + (currentPage + 1)+ "' title='转到第 " + (currentPage + 1) + " '>下一</a> ] "); } else { buff.append("[ 下一 ] "); } buff.append("</span>"); return buff.toString(); } /** * 输出码信息: 第${currentPage}/共${totalPage} * @return */ public String getPageCountHtml() { return "第" + currentPage + "/共" + getTotalPage() + ""; } /** * 输出 JavaScript 跳转函数代码 * @return */ public String getJavaScriptJumpCode() { if(StringUtil.isEmpty(pageUrl)) { return ""; } // 检查是否有参数符号, 没有就加上一个? if(pageUrl.indexOf("?") == -1) { pageUrl = pageUrl + '?'; } return "<script>" + "// 面跳转函数\n" + "// 参数: 包含码的表单元素,例如输入框,下拉框等\n" + "function jumpPage(input) {\n" + " // 码相同就不做跳转\n" + " if(input.value == " + currentPage + ") {" + " return;\n" + " }" + " var newUrl = '" + pageUrl + "&page=' + input.value;\n" + " document.location = newUrl;\n" + " }\n" + " </script>"; } /** * 输出面跳转的选择框和输入框. 示例输出: * <pre> 转到 <!-- 输出 HTML SELECT 元素, 并选中当前面编码 --> <select onchange='jumpPage(this);'> <c:forEach var="i" begin="1" end="${totalPage}"> <option value="${i}" <c:if test="${currentPage == i}"> selected </c:if> >第${i}</option> </c:forEach> </select> 输入码:<input type="text" value="${currentPage}" id="jumpPageBox" size="3"> <input type="button" value="跳转" onclick="jumpPage(document.getElementById('jumpPageBox'))"> </pre> * @return */ public String getPageFormJumpHtml() { String s = "转到\n" + "\t <!-- 输出 HTML SELECT 元素, 并选中当前面编码 -->\n" + " <select onchange='jumpPage(this);'>\n" + " \n"; for(int i = 1; i <= getTotalPage(); i++ ) { s += "<option value=" + i + "\n"; if(currentPage == i) { s+= " selected "; } s += "\t>第" + i + "</option>\n"; } s+= " </select>\n" + " 输入码:<input type=\"text\" value=\"" + currentPage + "\" id=\"jumpPageBox\" size=\"3\"> \n" + " <input type=\"button\" value=\"跳转\" onclick=\"jumpPage(document.getElementById('jumpPageBox'))\"> "; return s; } /** * 进行分页计算. */ private void calculate() { if (getPageCount() == 0) { setPageCount(1); } totalPage = (int) Math.ceil(1.0 * getRecordCount() / getPageCount()); // 总面数 if (totalPage == 0) totalPage = 1; // Check current page range, 2006-08-03 if(currentPage > totalPage) { currentPage = totalPage; } // System.out.println("currentPage=" + currentPage); // System.out.println("maxPage=" + maxPage); // // Fixed logic error at 2004-09-25 hasNextPage = currentPage < totalPage; hasPrevPage = currentPage > 1; return; } /** * @return Returns the 最大面数. */ public int getTotalPage() { calculate(); return totalPage; } /** * @param currentPage * The 最大面数 to set. */ @SuppressWarnings("unused") private void setTotalPage(int maxPage) { this.totalPage = maxPage; } /** * 是否有上一数据 */ public boolean hasPrevPage() { calculate(); return hasPrevPage; } /** * 是否有下一数据 */ public boolean hasNextPage() { calculate(); return hasNextPage; } // Test public static void main(String[] args) { PageBean pc = new PageBean(); pc.setCurrentPage(2); pc.setPageCount(4); pc.setRecordCount(5); pc.setPageUrl("product/list.do"); System.out.println("当前 " + pc.getCurrentPage()); System.out.println("有上一 " + pc.hasPrevPage()); System.out.println("有下一 " + pc.hasNextPage()); System.out.println("总面数 " + pc.getTotalPage()); System.out.println("分页 HTML 代码 " + pc.getPageJumpLinkHtml()); } /** * @return Returns the 当前码数. */ public int getCurrentPage() { return currentPage; } /** * 设置当前码, 从 1 开始. * @param currentPage * The 当前码数 to set. */ public void setCurrentPage(int currentPage) { if (currentPage <= 0) { currentPage = 1; } this.currentPage = currentPage; } /** * @return Returns the recordCount. */ public int getRecordCount() { return recordCount; } /** * @param recordCount * The recordCount to set. */ public void setRecordCount(int property1) { this.recordCount = property1; } /** * @return Returns the 每显示记录数. */ public int getPageCount() { return pageCount; } /** * @param pageCount * The 每显示记录数 to set. */ public void setPageCount(int pageCount) { this.pageCount = pageCount; } public String getPageUrl() { return pageUrl; } public void setPageUrl(String value) { pageUrl = value; } }

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

互联网极客

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

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

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

打赏作者

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

抵扣说明:

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

余额充值