浏览器分页技术

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

效果图展示:
这里写图片描述


这里写图片描述


这里写图片描述



基本框架(预览):
这里写图片描述



代码实现:
前端页面
主页(index.jsp)

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
  </head>

  <body>

     <!-- 经实测,c:redirect标记内不能用c:url -->
     <c:redirect url="/PageServlet"></c:redirect>
  </body>
</html>


servlet层
PageServlet.java

package cn.hncu.servlet;

import java.io.IOException;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import cn.hncu.service.IPageService;
import cn.hncu.service.PageServiceImpl;

public class PageServlet extends HttpServlet {
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    //注入service层
    IPageService service = new PageServiceImpl();
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doPost(request, response);
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //作用:拿到前端页面的用户选择的页面面数
        String pageNo = request.getParameter("pageNo");
        if(pageNo==null || "".equals(pageNo.trim())){//用户第一次进入分页页面还没有进行选择页面的情况
            pageNo = "1";
        }
        try {
            //将页面进行转换成整数的形式
            int iPageNo = Integer.valueOf(pageNo);//从前台页面拿到的数据!
            Map<String, Object> result = service.query(iPageNo);
            result.put("currentPage", iPageNo);//将当前页面同样封装到集合中去!
            /*
             * 理一下:map集合中一共封装了三个数据:1)总页数--dao层封装    2)所有数据行信息--dao层封装
             *      3)当前页数--servlet层进行封装
             */

            //数据封装完之后必须记得添加到容器中!
            request.setAttribute("result", result);
            //转发到前台页面进行相应的显示!
            request.getRequestDispatcher("/jsps/show.jsp").forward(request, response);

        } catch (NumberFormatException e) {
            response.getWriter().println("页面格式转换错误!");
        } catch (Exception e) {
            response.getWriter().println("数据库查询错误!");
        }

    }

}


service层
接口(PageService.java)

package cn.hncu.service;

import java.util.Map;

public interface IPageService {
    public abstract Map<String, Object> query(Integer pageNo) throws Exception;
}

实现类(PageServiceImpl.java)

package cn.hncu.service;

import java.util.Map;

import cn.hncu.dao.PageDAO;
import cn.hncu.dao.PageDAOJdbc;

public class PageServiceImpl implements IPageService {
    //以现在的技术还是只能够依赖注入,等学到后面就就可以更高级的方法弄了-----注入dao层
    PageDAO dao = new PageDAOJdbc();
    @Override
    public Map<String, Object> query(Integer pageNo) throws Exception {
        return dao.query(pageNo);
    }

}



DAO层
接口(PageDAO.java)

package cn.hncu.dao;

import java.util.Map;

public interface PageDAO {
    public abstract Map<String, Object> query(Integer pageNo) throws Exception; 
}

实现类(PageDAOImpl.java)

package cn.hncu.dao;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.MapListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;

import cn.hncu.pubs.C3p0Utils;

public class PageDAOJdbc implements PageDAO {

    @Override
    public Map<String, Object> query(Integer pageNo) throws Exception {
        //dao层进行封装的数据包含:1)一共包含多少页面  2)所有行数据
        Map<String, Object> result = new HashMap<String, Object>();
        //首选计算出总页数
        int pageSize = 10;
        //从数据库中拿到总行数!
        String sql = "select count(1) from person";
        QueryRunner run = new QueryRunner(C3p0Utils.getDataSource());
        Object obj = run.query(sql, new ScalarHandler());
        //转换成整数
        int rows = Integer.valueOf(String.valueOf(obj));//拿到总行数
        //根据总行数计算出纵页数
        int pageCount = rows/pageSize +(rows%pageSize==0?0:1);//页数
        //添加到集合中去
        result.put("pageCount", pageCount);

        int startN = (pageNo-1)*pageSize;
        sql = "select * from person limit "+startN+","+pageSize;
        //封装所有行数据
        List<Map<String, Object>> datas = run.query(sql, new MapListHandler());
        result.put("datas", datas);
        return result;
    }

}


DAO访问数据库中的数据



上面需要用到的工具类(拿到连接对象DbUtils)
C3p0Utils.java

package cn.hncu.pubs;

import java.sql.Connection;
import java.sql.SQLException;

import javax.sql.DataSource;

import com.mchange.v2.c3p0.ComboPooledDataSource;

public class C3p0Utils {
    //本地线程管理对象,用于实现: 同一个线程获取的连接是同一个
    private static ThreadLocal<Connection> t = new ThreadLocal<Connection>();

    private static DataSource pool =null;
    static{
        try {
            //配置文件和当前类放在一起
            pool = new ComboPooledDataSource();//使用默认配置项
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static DataSource getDataSource(){
        return pool;
    }

    public static Connection getConn() {
        //先从t中拿,如果有就拿出去,如果没有再到池中拿且把该对象放到t中
        Connection con = t.get();
        if(con==null){
            try {
                con = pool.getConnection();
                t.set(con); //放到t中
            } catch (SQLException e) {
                throw new RuntimeException(e.getMessage(), e);
            }
        }
        System.out.println("获取一个连接:"+con.hashCode());
        return con;
    }
}

相应的配置文件(c3p0-config.xml)

<c3p0-config>
    <!-- 默认配置,如果没有指定则使用这个配置 -->
    <default-config>
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <property name="jdbcUrl">
            <![CDATA[jdbc:mysql://127.0.0.1:3306/demo?useUnicode=true&characterEncoding=UTF-8]]>
        </property>
        <property name="user">root</property>
        <property name="password">1234</property>
        <!-- 初始化池大小 -->
        <property name="initialPoolSize">2</property>
        <!-- 最大空闲时间 -->
        <property name="maxIdleTime">30</property>
        <!-- 最多有多少个连接 -->
        <property name="maxPoolSize">10</property>
        <!-- 最少几个连接 -->
        <property name="minPoolSize">2</property>
        <!-- 每次最多可以执行多少个批处理语句 -->
        <property name="maxStatements">50</property>
    </default-config> 
    <!-- 命名的配置 -->
    <named-config name="demo">
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <property name="jdbcUrl">
            <![CDATA[jdbc:mysql://127.0.0.1:3306/demo?useUnicode=true&characterEncoding=UTF-8]]>
        </property>
        <property name="user">root</property>
        <property name="password">1234</property>
        <property name="acquireIncrement">5</property><!-- 如果池中数据连接不够时一次增长多少个 -->
        <property name="initialPoolSize">10</property>
        <property name="minPoolSize">5</property>
        <property name="maxPoolSize">15</property>
        <property name="maxStatements">0</property>
        <property name="maxStatementsPerConnection">5</property> <!-- he's important, but there's only one of him -->
    </named-config>
</c3p0-config> 


结果页面显示
show.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <style type="text/css">
        table{
            border: 1px solid red;
            border-collapse: collapse;
            width: 150px;
        }
        td{
            border: 1px solid red;
        }
    </style>
    <title>分页结果页面</title>
    <script type="text/javascript">
        function sub(obj){
            window.location.href="<c:url value='/PageServlet?pageNo="+obj.value+"' />";
        }
    </script>

  </head>

  <body>
    <!-- 前端页面实现用到的技术:JSTL(c标签--很强!)+EL表达式 -->
    <!-- 下面是把所有的数据全部输出来了 -->
    <table>
        <tr> <th>学号</th> <th>姓名</th> </tr>
        <c:forEach items="${result.datas}" var="map">
            <tr> <td>${map.id}</td> <td>${map.name }</td> </tr>
        </c:forEach>
    </table>
    <hr/>

    <!-- 在这个上面添加上一页的功能(添加这个功能之前还需要判断当前页面是否为第一页,如果为第一页则不显示上一页) -->
    <c:if test="${result.currentPage!=1 }">
        <a href="<c:url value='/PageServlet?pageNo=${result.currentPage-1}' />">
            上一页
        </a>
        &nbsp;
    </c:if>
    <c:forEach begin="1" end="${result.pageCount }" var="idx">
        <!-- 给页面添加超链接操作! -->
        <c:if test="${result.currentPage!=idx }">
            <!-- 超链接方式进行传参 -->
            <a href="<c:url value='/PageServlet?pageNo=${idx }'/>"><!-- 这种写法穿透能力很强啊! -->
                ${idx }
            </a>
        </c:if>
        <c:if test="${result.currentPage==idx }">
            ${idx }
        </c:if>
        &nbsp;&nbsp;
    </c:forEach>

    <!-- 在这个下面添加下一页的功能(添加这个功能之前还需要判断当前页面是否为最后一页,如果为最后一页则不显示下一页) -->
    <c:if test="${result.currentPage!=result.pageCount }">
        <a href="<c:url value='/PageServlet?pageNo=${result.currentPage+1}' />">
            下一页
        </a>
    </c:if>


    <!-- 接下来演示一个淘汰的技术--也不算淘汰吧,就是现在的技术基本不用这个功能了 -->
    <br/><br/>
    <select onchange="sub(this)">
        <c:forEach begin="1" end="${result.pageCount }" var="idx">
            <option <c:if test="${idx==result.currentPage }">selected="selected"</c:if> value="${idx }">第${idx }页</option>
        </c:forEach>
    </select>
  </body>
</html>

猜你喜欢

转载自blog.csdn.net/qq_33621967/article/details/53246926
今日推荐