09-JavaWeb-分页

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/linzhaoliangyan/article/details/88621104

1 分页

1.1 分页和页码思路

       * 已知

         * 每页条数:pageSize

         * 总条数:totalRecord

         * 请求当前页:pageNum

      *  算出来

          * 总页数:totalPage

                * 当可以整除的时候:totalPage=totalRecord/pageSize

                * 当不可以整除的时候:totalPage=totalRecord/pageSize+1

          *起始坐标:startIndex

mysql:
SELECT * FROM emp LIMIT 0,3;
SELECT * FROM emp LIMIT 3,3;
SELECT * FROM emp LIMIT 6,3;
SELECT * FROM emp LIMIT 9,3;
SELECT * FROM emp LIMIT 12,3;
n=pageNum-1(pageNum从1开始)
SELECT * FROM emp LIMIT n*pageSize,pageSize;

oracle:
select * from (select rownum rn ,t.* from tt12 t where rownum<8) where rn>4;

startIndex=(pageNum-1)*pageSize      

          * 分页的页数

            * start

            * end 

            * 假如也是1,2,3,4,5,start为1,end为5

            * 思路

                * 假如总页数小于等于5,start=1,end=totalPage

                * 假如总页数大于5,start=pageNum-2,end=pageNum+2

                        * 假如pageNum=8,start=6,end=10

                * 边界判断

                    * 当start小于等于0:start=1,end=5

                    * 当end大于等于totalPage:start= totalPage-5,end=totalPage     

* 集合

            * List<T>

       * dao层 

            * int findCount();

            * List<T> findTByPageNum(int startIndex,int pageSize);

       * 服务层

            * 一些校验和业务相关

            * 调用dao层代码获取List<T>

       * 控制层(Serlvet

            * 获取传递过参数(pageNum)

            *  List<T> findTByPageNum(int startIndex,int pageSize);

       * 展示层

            * 假如当前页为第一页,就没有上一页,显示下一页

            * 假如当前不是第一页,页不是最后一页,显示上一页,显示下一页

            * 假如当前页是最后一页,就没有下页,显示上一页

1.2 开发步骤

     1.2.1 数据库表搭建

1.2.2 数据库驱动,数据库连接池,DbUtils,JSTLjar引入

1.2.3 数据库连接池(c3p0)配置文件

<?xml version="1.0" encoding="UTF-8"?>
<!-- c3p0-config.xml必须位于类路径下面 private static ComboPooledDataSource ds; static{ 
    try { ds = new ComboPooledDataSource("MySQL"); } catch (Exception e) { throw 
    new ExceptionInInitializerError(e); } } -->

<c3p0-config>
    <!-- C3P0的缺省(默认)配置, 如果在代码中“ComboPooledDataSource ds = new ComboPooledDataSource();”这样写就表示使用的是C3P0的缺省(默认)配置信息来创建数据源 -->
    <default-config>
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql://127.0.0.1:3306/etc0102</property>
        <property name="user">root</property>
        <property name="password">root</property>

        <property name="acquireIncrement">5</property>
        <property name="initialPoolSize">10</property>
        <property name="minPoolSize">5</property>
        <property name="maxPoolSize">20</property>
    </default-config>

    <!-- C3P0的命名配置, 如果在代码中“ComboPooledDataSource ds = new ComboPooledDataSource("MySQL");”这样写就表示使用的是name是MySQL的配置信息来创建数据源 -->
    <named-config name="MySQL">
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql://127.0.0.1:3306/etc0102</property>
        <property name="user">root</property>
        <property name="password">root</property>

        <property name="acquireIncrement">5</property>
        <property name="initialPoolSize">10</property>
        <property name="minPoolSize">5</property>
        <property name="maxPoolSize">20</property>
    </named-config>

</c3p0-config>

public class JDBCUtils_C3P0 {
    private static ComboPooledDataSource ds = null;
    // 在静态代码块中创建数据库连接池
    static {
        try {
            ds = new ComboPooledDataSource("MySQL");
        } catch (Exception e) {
            throw new ExceptionInInitializerError(e);
        }
    }

    public static ComboPooledDataSource getDataSource() {
        return ds;
    }

    public static Connection getConnection() throws SQLException {
        // 从数据源中获取数据库连接
        return ds.getConnection();
    }

    /**
     * 关闭的方法 Statement:通过定义父接口,如果传入的参数是Preparestatement也通用
     */
    public static void close(Connection conn, Statement stmt, ResultSet rs) {
        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (stmt != null) {
            try {
                stmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (conn != null) {// 如果连接不为空
            try {
                if (!conn.isClosed()) {// 如果连接没有关闭
                    conn.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }

        }
    }
}

 1.2.5 账户实体编写

public class Account {
    private int id;
    private String name;
    private double money;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getMoney() {
        return money;
    }

    public void setMoney(double money) {
        this.money = money;
    }

    @Override
    public String toString() {
        return "Account [id=" + id + ", name=" + name + ", money=" + money + "]";
    }

}
public class AccountDao {

    // 查询所有记录
    public int findCount() throws SQLException {
        QueryRunner queryRunner = new QueryRunner(JDBCUtils_C3P0.getDataSource());
        String sql = "select count(*) from account";
        Long count = queryRunner.query(sql, new ScalarHandler<Long>());
        return count.intValue();
    }

    // 根据下标和每页条数,查询账户列表
    public List<Account> findAcountByPageNum(int startIndex, int pageSize) throws SQLException {
        QueryRunner queryRunner = new QueryRunner(JDBCUtils_C3P0.getDataSource());
        String sql="select * from account limit ?,?";
        List<Account> accounts = queryRunner.query(sql, new BeanListHandler<Account>(Account.class), startIndex,pageSize);
        return accounts;
    }
    
    
}
Dao层单元测试
@Test
    public void test1() throws SQLException {
        AccountDao accountDao=new AccountDao();
        int count = accountDao.findCount();
        System.out.println(count);
    }
    

    @Test
    public void test2() throws SQLException {
        AccountDao accountDao=new AccountDao();
        List<Account> accounts = accountDao.findAcountByPageNum(0, 10);
        System.out.println(accounts);
    }
分页PageBean的编写
public class PageBean<T> {
    // 已知
    // 每页条数:pageSize
    private int pageSize;
    // 总条数:totalRecord
    private int totalRecord;
    // 请求当前页:pageNum
    private int pageNum;
    // 集合
    private List<T> list;

    // 计算出来
    // 总页数:totalPage
    private int totalPage;
    // 起始坐标:startIndex
    private int startIndex;
    // 当前start,end,假如分页1,2,3,4,5,start=1,end=5
    private int start;
    private int end;

    public int getPageSize() {
        return pageSize;
    }

    public void setPageSize(int pageSize) {
        this.pageSize = pageSize;
    }

    public int getTotalRecord() {
        return totalRecord;
    }

    public void setTotalRecord(int totalRecord) {
        this.totalRecord = totalRecord;
    }

    public int getPageNum() {
        return pageNum;
    }

    public void setPageNum(int pageNum) {
        this.pageNum = pageNum;
    }

    public List<T> getList() {
        return list;
    }

    public void setList(List<T> list) {
        this.list = list;
    }

    public int getTotalPage() {
        return totalPage;
    }

    public int getStartIndex() {
        return startIndex;
    }

    public int getStart() {
        return start;
    }

    public int getEnd() {
        return end;
    }

    // 构建器
    public PageBean(int pageSize, int totalRecord, int pageNum) {
        super();
        this.pageSize = pageSize;
        this.totalRecord = totalRecord;
        this.pageNum = pageNum;
        // * 总页数:totalPage
        // * 当可以整除的时候:totalPage=totalRecord/pageSize
        // * 当不可以整除的时候:totalPage=totalRecord/pageSize+1
        if (totalRecord % pageSize == 0) {// 可以整除的时候
            totalPage = totalRecord / pageSize;
        } else {
            totalPage = totalRecord / pageSize + 1;
        }

        startIndex = (pageNum - 1) * pageSize;
        
//       * 思路
//         * 假如总页数小于等于5,start=1,end=totalPage
//         * 假如总页数大于5,start=pageNum-2,end=pageNum+2
//                 * 假如pageNum=8,start=6,end=10
//         * 边界判断
//             * 当start小于0:start=1,end=5
//             * 当end大于totalPage:start= totalPage-5,end=totalPage     
        start = 1;
        end = 5;
        if(totalPage<=5) {
            end=totalPage;
        }else {
            start=pageNum-2;
            end=pageNum+2;
            if(start<=0) {
                start = 1;
                end = 5;
            }
            if(end>=totalPage) {
                start=totalPage-5;
                end=totalPage;
            }
        }
    }

}
Service的层编写
public class UserService {

    public PageBean<Account> findAllAccount(int pageNum, int pageSize) throws SQLException {
        AccountDao accountdao = new AccountDao();
        int totalRecord = accountdao.findCount();
        PageBean<Account> pageBean = new PageBean<Account>(pageSize, totalRecord, pageNum);
        int startIndex = pageBean.getStartIndex();
        List<Account> accounts = accountdao.findAcountByPageNum(startIndex, pageSize);
        pageBean.setList(accounts);
        return pageBean;
    }
}

Service的层单元测试
@Test
    public void test3() throws SQLException {
        UserService userService=new UserService();
        PageBean<Account> pageBean = userService.findAllAccount(1, 10);
        System.out.println(pageBean);
    }

 Servlet层的编写(控制层)
@WebServlet("/query")
public class QueryAccountByPageServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
       
    /**
     * @see HttpServlet#HttpServlet()
     */
    public QueryAccountByPageServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 1 设置编码
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");
        // 2 获取请求参数
        String num = request.getParameter("num");
        if(num==null) {
            num="1";
        }
        int pageNum=Integer.parseInt(num);
        int pageSize=10;
        // 3 查询列表
        UserService userService=new UserService();
        try {
            PageBean<Account> pageBean = userService.findAllAccount(pageNum, pageSize);
            
        // 4 设置到request域中
            request.setAttribute("pageBean", pageBean);
            
        // 5 请求转发到列表显示页面
            request.getRequestDispatcher("/list.jsp").forward(request, response);
        } catch (SQLException e) {
            e.printStackTrace();
            request.setAttribute("msg", "系统暂时维护,请联系管理员");
            request.getRequestDispatcher("/error.jsp").forward(request, response);
        }
    }

    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        doGet(request, response);
    }

}

 JSP页面展示(视图层(View))

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Insert title here</title>
<style type="text/css">
table.gridtable {
    font-family: verdana, arial, sans-serif;
    font-size: 11px;
    color: #333333;
    border-width: 1px;
    border-color: #666666;
    border-collapse: collapse;
}

table.gridtable th {
    border-width: 1px;
    padding: 8px;
    border-style: solid;
    border-color: #666666;
    background-color: #dedede;
}

table.gridtable td {
    border-width: 1px;
    padding: 8px;
    border-style: solid;
    border-color: #666666;
    background-color: #ffffff;
}
</style>
</head>
<body>
    <h1>列表显示</h1>
    <table class="gridtable">
        <tr>
            <th>id</th>
            <th>姓名</th>
            <th>金额</th>
        </tr>
        <c:forEach items="${pageBean.list }" var="account">
            <tr>
                <td>${account.id }</td>
                <td>${account.name }</td>
                <td>${account.money }</td>
            <tr>
        </c:forEach>

        <!--  * 假如当前页为第一页,就没有上一页,显示下一页
                  * 假如当前不是第一页,页不是最后一页,显示上一页,显示下一页
                  * 假如当前页是最后一页,就没有下页,显示上一页 -->
    </table>
    
    <%-- 构建分页导航 --%>
    共有${requestScope.pageBean.totalRecord}个员工,共${requestScope.pageBean.totalPage }页,当前为${requestScope.pageBean.pageNum}页
    <br />
    <a href="${pageContext.request.contextPath}/query?num=1">首页</a>
    <%--如果当前页为第一页时,就没有上一页这个超链接显示 --%>
    <c:if test="${requestScope.pageBean.pageNum ==1}">
        <c:forEach begin="${requestScope.pageBean.start}"
            end="${requestScope.pageBean.end}" step="1" var="i">
            <c:if test="${requestScope.pageBean.pageNum == i}">
                        ${i}
                    </c:if>
            <c:if test="${requestScope.pageBean.pageNum != i}">
                <a href="${pageContext.request.contextPath}/query?num=${i}">${i}</a>
            </c:if>
        </c:forEach>
        <a
            href="${pageContext.request.contextPath}/query?num=${requestScope.pageBean.pageNum+1}">下一页</a>
    </c:if>

    <%--如果当前页不是第一页也不是最后一页,则有上一页和下一页这个超链接显示 --%>
    <c:if
        test="${requestScope.pageBean.pageNum > 1 && requestScope.pageBean.pageNum < requestScope.pageBean.totalPage}">
        <a
            href="${pageContext.request.contextPath}/query?num=${requestScope.pageBean.pageNum-1}">上一页</a>
        <c:forEach begin="${requestScope.pageBean.start}"
            end="${requestScope.pageBean.end}" step="1" var="i">
            <c:if test="${requestScope.pageBean.pageNum == i}">
                        ${i}
                    </c:if>
            <c:if test="${requestScope.pageBean.pageNum != i}">
                <a href="${pageContext.request.contextPath}/query?num=${i}">${i}</a>
            </c:if>
        </c:forEach>
        <a
            href="${pageContext.request.contextPath}/query?num=${requestScope.pageBean.pageNum+1}">下一页</a>
    </c:if>

    <%-- 如果当前页是最后一页,则只有上一页这个超链接显示,下一页没有 --%>
    <c:if
        test="${requestScope.pageBean.pageNum == requestScope.pageBean.totalPage}">
        <a
            href="${pageContext.request.contextPath}/query?num=${requestScope.pageBean.pageNum-1}">上一页</a>
        <c:forEach begin="${requestScope.pageBean.start}"
            end="${requestScope.pageBean.end}" step="1" var="i">
            <c:if test="${requestScope.pageBean.pageNum == i}">
                        ${i}
                    </c:if>
            <c:if test="${requestScope.pageBean.pageNum != i}">
                <a href="${pageContext.request.contextPath}/query?num=${i}">${i}</a>
            </c:if>
        </c:forEach>
    </c:if>
    <%--尾页 --%>
    <a
        href="${pageContext.request.contextPath}/query?num=${requestScope.pageBean.totalPage}">尾页</a>
</body>
</html>


<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Insert title here</title>
</head>
<body>
    <h1 style="color: red">
        ${msg }
    </h1>
</body>
</html>

猜你喜欢

转载自blog.csdn.net/linzhaoliangyan/article/details/88621104
今日推荐