• 对慕课网分页感悟二


      上一次我们使用list集合里面的方法sublist实现了分页功能,但是这一种方法虽然能直接的实现分页,具体需要直接将所有的数据取出来然后再进行分页使用,如果数据较多的话,我们就不便使用这种方法更适合使用sql语句里面的limit关键字就能比较迅速的实现分页的功能,话不多说。

      首先,看看连接数据库的JdbcUtil.java,这一个和上一次的并没有不同。

      

    package com.imooc.page.util;
    
    import java.io.InputStream;
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.ResultSetMetaData;
    import java.sql.SQLException;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    import java.util.Properties;
    
    public class JdbcUtil {
    
        // 表示定义数据库的用户名
        private static String USERNAME ;
    
        // 定义数据库的密码
        private static String PASSWORD;
    
        // 定义数据库的驱动信息
        private static String DRIVER;
    
        // 定义访问数据库的地址
        private static String URL;
    
        // 定义数据库的链接
        private Connection connection;
    
        // 定义sql语句的执行对象
        private PreparedStatement pstmt;
    
        // 定义查询返回的结果集合
        private ResultSet resultSet;
        
        static{
            //加载数据库配置信息,并给相关的属性赋值
            loadConfig();
        }
    
        /**
         * 加载数据库配置信息,并给相关的属性赋值
         */
        public static void loadConfig() {
            try {
                InputStream inStream = JdbcUtil.class
                        .getResourceAsStream("/jdbc.properties");
                Properties prop = new Properties();
                prop.load(inStream);
                USERNAME = prop.getProperty("jdbc.username");
                PASSWORD = prop.getProperty("jdbc.password");
                DRIVER= prop.getProperty("jdbc.driver");
                URL = prop.getProperty("jdbc.url");
            } catch (Exception e) {
                throw new RuntimeException("读取数据库配置文件异常!", e);
            }
        }
    
        public JdbcUtil() {
    
        }
    
        /**
         * 获取数据库连接
         * 
         * @return 数据库连接
         */
        public Connection getConnection() {
            try {
                Class.forName(DRIVER); // 注册驱动
                connection = DriverManager.getConnection(URL, USERNAME, PASSWORD); // 获取连接
            } catch (Exception e) {
                throw new RuntimeException("get connection error!", e);
            }
            return connection;
        }
    
        /**
         * 执行更新操作
         * 
         * @param sql
         *            sql语句
         * @param params
         *            执行参数
         * @return 执行结果
         * @throws SQLException
         */
        public boolean updateByPreparedStatement(String sql, List<?> params)
                throws SQLException {
            boolean flag = false;
            int result = -1;// 表示当用户执行添加删除和修改的时候所影响数据库的行数
            pstmt = connection.prepareStatement(sql);
            int index = 1;
            // 填充sql语句中的占位符
            if (params != null && !params.isEmpty()) {
                for (int i = 0; i < params.size(); i++) {
                    pstmt.setObject(index++, params.get(i));
                }
            }
            result = pstmt.executeUpdate();
            flag = result > 0 ? true : false;
            return flag;
        }
    
        /**
         * 执行查询操作
         * 
         * @param sql
         *            sql语句
         * @param params
         *            执行参数
         * @return
         * @throws SQLException
         */
        public List<Map<String, Object>> findResult(String sql, List<?> params)
                throws SQLException {
            List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
            int index = 1;
            pstmt = connection.prepareStatement(sql);
            if (params != null && !params.isEmpty()) {
                for (int i = 0; i < params.size(); i++) {
                    pstmt.setObject(index++, params.get(i));
                }
            }
            resultSet = pstmt.executeQuery();
            ResultSetMetaData metaData = resultSet.getMetaData();
            int cols_len = metaData.getColumnCount();
            while (resultSet.next()) {
                Map<String, Object> map = new HashMap<String, Object>();
                for (int i = 0; i < cols_len; i++) {
                    String cols_name = metaData.getColumnName(i + 1);
                    Object cols_value = resultSet.getObject(cols_name);
                    if (cols_value == null) {
                        cols_value = "";
                    }
                    map.put(cols_name, cols_value);
                }
                list.add(map);
            }
            return list;
        }
    
        /**
         * 释放资源
         */
        public void releaseConn() {
            if (resultSet != null) {
                try {
                    resultSet.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (pstmt != null) {
                try {
                    pstmt.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (connection != null) {
                try {
                    connection.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    
        public static void main(String[] args) {
            JdbcUtil jdbcUtil = new JdbcUtil();
            jdbcUtil.getConnection();
            try {
                List<Map<String, Object>> result = jdbcUtil.findResult(
                        "select * from t_student", null);
                for (Map<String, Object> m : result) {
                    System.out.println(m);
                }
            } catch (SQLException e) {
                e.printStackTrace();
            } finally {
                jdbcUtil.releaseConn();
            }
        }
    }
    ------------------------------------------------------------JdbcUtil.java-----------------------------------------------
    jdbc.username=root jdbc.password=123456 jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://127.0.0.1:3306/imooc

    好,看完连接我们就来看一下实体类层:

      

    -------------------------------------------------------------Student.java-------------------------------------------------------
    package
    com.imooc.page.model; import java.io.Serializable; import java.util.Map; public class Student implements Serializable { private static final long serialVersionUID = -7476381137287496245L; private int id; //学生记录id private String stuName;//学生姓名 private int age; //学生年龄 private int gender; //学生性别 private String address;//学生住址 public Student() { super(); } public Student(int id, String stuName, int age, int gender, String address) { super(); this.id = id; this.stuName = stuName; this.age = age; this.gender = gender; this.address = address; } public Student(Map<String, Object> map){ this.id = (int)map.get("id"); this.stuName = (String)map.get("stu_name"); this.age = (int)map.get("age"); this.gender = (int)map.get("gender"); this.address = (String)map.get("address"); } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getStuName() { return stuName; } public void setStuName(String stuName) { this.stuName = stuName; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public int getGender() { return gender; } public void setGender(int gender) { this.gender = gender; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } @Override public String toString() { return "Student [id=" + id + ", stuName=" + stuName + ", age=" + age + ", gender=" + gender + ", address=" + address + "]"; } }
    ------------------------------------------------------Pager<T>.java-----------------------------------------------
    package
    com.imooc.page.model; import java.io.Serializable; import java.util.List; public class Pager<T> implements Serializable { private static final long serialVersionUID = -8741766802354222579L; private int pageSize; // 每页显示多少条记录 private int currentPage; //当前第几页数据 private int totalRecord; // 一共多少条记录 private int totalPage; // 一共多少页记录 private List<T> dataList; //要显示的数据 public Pager(int pageNum, int pageSize, List<T> sourceList){ if(sourceList == null || sourceList.isEmpty()){ return; } // 总记录条数 this.totalRecord = sourceList.size(); // 每页显示多少条记录 this.pageSize = pageSize; //获取总页数 this.totalPage = this.totalRecord / this.pageSize; if(this.totalRecord % this.pageSize !=0){ this.totalPage = this.totalPage + 1; } // 当前第几页数据 this.currentPage = this.totalPage < pageNum ? this.totalPage : pageNum; // 起始索引 int fromIndex = this.pageSize * (this.currentPage -1); // 结束索引 int toIndex = this.pageSize * this.currentPage > this.totalRecord ? this.totalRecord : this.pageSize * this.currentPage; this.dataList = sourceList.subList(fromIndex, toIndex); } public Pager(){ } public Pager(int pageSize, int currentPage, int totalRecord, int totalPage, List<T> dataList) { super(); this.pageSize = pageSize; this.currentPage = currentPage; this.totalRecord = totalRecord; this.totalPage = totalPage; this.dataList = dataList; } public int getPageSize() { return pageSize; } public void setPageSize(int pageSize) { this.pageSize = pageSize; } public int getCurrentPage() { return currentPage; } public void setCurrentPage(int currentPage) { this.currentPage = currentPage; } public int getTotalRecord() { return totalRecord; } public void setTotalRecord(int totalRecord) { this.totalRecord = totalRecord; } public int getTotalPage() { return totalPage; } public void setTotalPage(int totalPage) { this.totalPage = totalPage; } public List<T> getDataList() { return dataList; } public void setDataList(List<T> dataList) { this.dataList = dataList; } }

    看完上面的代码我们可以比较明显的看出来两者并没有什么不同。

    不多说,我们直接看控制层servlet:

      

    ---------------------------------------------------------JdbcSqlServlet.java------------------------------------------------
    package
    com.imooc.page.servlet; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.imooc.page.Constant; import com.imooc.page.model.Pager; import com.imooc.page.model.Student; import com.imooc.page.service.JdbcSqlStudentServiceImpl; import com.imooc.page.service.StudentService; import com.imooc.page.util.StringUtil; public class JdbcSqlServlet extends HttpServlet { private static final long serialVersionUID = -318134993070614515L; private StudentService studentService = new JdbcSqlStudentServiceImpl(); public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 接收request里的参数 String stuName = request.getParameter("stuName"); //学生姓名 // 获取学生性别 int gender = Constant.DEFAULT_GENDER; String genderStr = request.getParameter("gender"); if(genderStr!=null && !"".equals(genderStr.trim())){ gender = Integer.parseInt(genderStr); } // 校验pageNum参数输入合法性 String pageNumStr = request.getParameter("pageNum"); if(pageNumStr !=null && !StringUtil.isNum(pageNumStr)){ request.setAttribute("errorMsg", "参数传输错误"); request.getRequestDispatcher("jdbcSqlStudent.jsp").forward(request, response); return; } int pageNum = Constant.DEFAULT_PAGE_NUM; //显示第几页数据 if(pageNumStr!=null && !"".equals(pageNumStr.trim())){ pageNum = Integer.parseInt(pageNumStr); } int pageSize = Constant.DEFAULT_PAGE_SIZE; // 每页显示多少条记录 String pageSizeStr = request.getParameter("pageSize"); if(pageSizeStr!=null && !"".equals(pageSizeStr.trim())){ pageSize = Integer.parseInt(pageSizeStr); } // 组装查询条件 Student searchModel = new Student(); searchModel.setStuName(stuName); searchModel.setGender(gender); //调用service 获取查询结果 Pager<Student> result = studentService.findStudent(searchModel,pageNum, pageSize); // 返回结果到页面 request.setAttribute("result", result); request.setAttribute("stuName", stuName); request.setAttribute("gender", gender); request.getRequestDispatcher("jdbcSqlStudent.jsp").forward(request, response); } }

      servlce层也能看到是完全的一致。

    -----------------------------------------------------------JdbcSqlStudentServiceImpl.java-------------------------------------------
    package
    com.imooc.page.service; import com.imooc.page.dao.JdbcSqlStudentDaoImpl; import com.imooc.page.dao.StudentDao; import com.imooc.page.model.Pager; import com.imooc.page.model.Student; public class JdbcSqlStudentServiceImpl implements StudentService { private StudentDao studentDao; public JdbcSqlStudentServiceImpl(){ studentDao = new JdbcSqlStudentDaoImpl(); } @Override public Pager<Student> findStudent(Student searchModel, int pageNum, int pageSize) { Pager<Student> result = studentDao.findStudent(searchModel, pageNum, pageSize); return result; } }

       我们前面一直在说是使用了sql语句里面的关键字limit,可想而知,在Dao层肯定是有所不同的。

      

    -----------------------------------------------------JdbcSqlStudentDaoImpl.java----------------------------------------
    package
    com.imooc.page.dao; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import java.util.Map; import com.imooc.page.Constant; import com.imooc.page.model.Pager; import com.imooc.page.model.Student; import com.imooc.page.util.JdbcUtil; /** * 使用mysql数据库limit关键字实现分页 * * @author lenjey * */ public class JdbcSqlStudentDaoImpl implements StudentDao { @Override public Pager<Student> findStudent(Student searchModel, int pageNum, int pageSize) { Pager<Student> result = null; // 存放查询参数 List<Object> paramList = new ArrayList<Object>(); String stuName = searchModel.getStuName(); int gender = searchModel.getGender(); StringBuilder sql = new StringBuilder( "select * from t_student where 1=1"); StringBuilder countSql = new StringBuilder( "select count(id) as totalRecord from t_student where 1=1 "); if (stuName != null && !stuName.equals("")) { sql.append(" and stu_name like ?"); countSql.append(" and stu_name like ?"); paramList.add("%" + stuName + "%"); } if (gender == Constant.GENDER_FEMALE || gender == Constant.GENDER_MALE) { sql.append(" and gender = ?"); countSql.append(" and gender = ?"); paramList.add(gender); } // 起始索引 //这里的话,个人觉得并没有处理好 int fromIndex = pageSize * (pageNum -1); // System.out.println(fromIndex); // 使用limit关键字,实现分页 sql.append(" limit " + fromIndex + ", " + pageSize ); // 存放所有查询出的学生对象 List<Student> studentList = new ArrayList<Student>(); JdbcUtil jdbcUtil = null; try { jdbcUtil = new JdbcUtil(); jdbcUtil.getConnection(); // 获取数据库链接 // 获取总记录数 List<Map<String, Object>> countResult = jdbcUtil.findResult(countSql.toString(), paramList); //在获取总数的时候,我们需要使用这种方法来进行获取 Map<String, Object> countMap = countResult.get(0); int totalRecord = ((Number)countMap.get("totalRecord")).intValue(); // 获取查询的学生记录 List<Map<String, Object>> studentResult = jdbcUtil.findResult(sql.toString(), paramList); if (studentResult != null) { for (Map<String, Object> map : studentResult) { Student s = new Student(map); studentList.add(s); } } //获取总页数 int totalPage = totalRecord / pageSize; if(totalRecord % pageSize !=0){ totalPage++; } // 组装pager对象 result = new Pager<Student>(pageSize, pageNum, totalRecord, totalPage, studentList); } catch (SQLException e) { throw new RuntimeException("查询所有数据异常!", e); } finally { if (jdbcUtil != null) { jdbcUtil.releaseConn(); // 一定要释放资源 } } return result; } }

      不知道又没有看出来,两个dao层调用pager里面的方法是不一样的,一个是调用在modal直接获取分页需要的数据

      而后者则是直接给之赋值即可。

      好,后台我们看完了,剩下的我们看前台。

      前台里面呢?我们用了一个插件。

    这个插件能比较形象的将分页功能显示出来,比以往我们所用的感觉更好,用户体验更好。

    具体这里就不再赘述了。

      

    <%@ 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">
    <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
    <%@taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>学生信息</title>
    </head>
    <%
        // 获取请求的上下文
        String context = request.getContextPath();
    %>
    <link href="../css/pagination.css" rel="stylesheet" type="text/css" />
    <script type="text/javascript" src="../js/jquery-1.11.3.js"></script>
    <script type="text/javascript" src="../js/jquery.pagination.js"></script>
    <script type="text/javascript">
    
    // 点击分页按钮以后触发的动作
    function handlePaginationClick(new_page_index, pagination_container) {
        $("#stuForm").attr("action", "<%=context%>/jdbcSql/JdbcSqlServlet?pageNum=" + (new_page_index+1));
        $("#stuForm").submit();
        return false;
    }
    
    $(function(){
        $("#News-Pagination").pagination(${result.totalRecord}, {
            items_per_page : ${result.pageSize}, // 每页显示多少条记录
            current_page:${result.currentPage} - 1, // 当前显示第几页数据
            num_display_entries:8, // 分页显示的条目数
            next_text:"下一页",
            prev_text:"上一页",
            num_edge_entries:2, // 连接分页主体,显示的条目数
            callback:handlePaginationClick
        }); 
        
        // 设置学生默认性别
        $("#gender").val("${gender}");
    });
    </script>
    <body>
        <div style="margin-left: 100px; margin-top: 100px;">
            <div>
                <font color="red">${errorMsg }</font>
            </div>
            <div>
                <form action="<%=context%>/jdbcSql/JdbcSqlServlet" id="stuForm"
                    method="post">
                    姓名 <input type="text" name="stuName" id="stu_name"
                        style=" 120px" value="${stuName }"> &nbsp; 性别 <select
                        name="gender" id="gender" style=" 80px">
                        <option value="0">全部</option>
                        <option value="1">男</option>
                        <option value="2">女</option>
                    </select> &nbsp;&nbsp; <input type="submit" value="查询">
                </form>
            </div>
            <br> 学生信息列表:<br> <br>
            <!-- 后台返回结果为空 -->
            <c:if test="${fn:length(result.dataList) eq 0 }">
                <span>查询的结果不存在</span>
            </c:if>
    
            <!-- 后台返回结果不为空 -->
            <c:if test="${fn:length(result.dataList) gt 0 }">
                <table border="1px" cellspacing="0px"
                    style="border-collapse: collapse">
                    <thead>
                        <tr height="30">
                            <th width="130">姓名</th>
                            <th width="130">性别</th>
                            <th width="130">年龄</th>
                            <th width="190">家庭地址</th>
                        </tr>
                    </thead>
                    <c:forEach items="${result.dataList }" var="student">
                        <tr>
                            <td><c:out value="${student.stuName }"></c:out></td>
                            <td><c:if test="${ student.gender eq 1}">男</c:if> <c:if
                                    test="${ student.gender eq 2}">女</c:if></td>
                            <td><c:out value="${student.age }"></c:out></td>
                            <td><c:out value="${student.address }"></c:out></td>
                        </tr>
                    </c:forEach>
                </table>
                <br>
                <div id="News-Pagination"></div>
            </c:if>
        </div>
    </body>
    </html>

    好了,这个就到这里了。

  • 相关阅读:
    基本控件文档-UIView属性---iOS-Apple苹果官方文档翻译
    基本控件文档-UITextField属性---iOS-Apple苹果官方文档翻译
    vue后台管理权限篇
    JavaScript call、apply、bind的用法
    Array map()方法
    markdown常用语法总结
    webpack配置说明
    Object.prototype.toString.call(value)
    前后端数据交互和前端数据展示
    vue常用的传值方式
  • 原文地址:https://www.cnblogs.com/strator/p/7637718.html
Copyright © 2020-2023  润新知