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的调用方法,具体代码就不再过多显示。
代码有何不懂,可以跟帖回问。仅供参考!

猜你喜欢

转载自blog.csdn.net/jsqfengbao/article/details/78813417