使用C3P0数据库连接池分页显示数据

分页显示数据

前提:准备好jar包,c3p0-config.xml配置文件,以及C3P0Util工具类
除了几个jar包,之前C3P0数据库连接池带有解释
https://blog.csdn.net/weixin_43968510/article/details/90739720

新建一个JavaWeb项目

在这里插入图片描述
在这里插入图片描述

2.建立包结构

在这里插入图片描述

使用MVC模式(模型-视图-控制器)
各个包的作用:------>
dao层:主要是数据库的操作
entity:存放实体类
service层:业务逻辑层
util:存放工具类
web:存放servlet类
细节:------------------->
servlet类:起一个获取参数,调用业务逻辑,分发转向的作用
而像c3p0-config.xml配置文件就是在根目录下

细化的每个包下的文件

在这里插入图片描述

像dao,service包下存放接口,然后在imple包下再写这些接口的实现类

3.导入相关jar包

在这里插入图片描述

c3p0-0.9.1.2.jar是C3p0连接池的jar包
commons-dbutils-1.4.jar是DButils框架
jstl-1.2.jar是核心标签库,后面分页显示数据会用到
mysql-connector-java-5.1.37-bin.jar是MySQL数据库连接的jar包

4.先准备实体类

在这里插入图片描述
1.代码如下,注意包结构,以及字段名,字段类型
在这里插入图片描述

细节:最后一个字段 deptId不用写

package wh.entity;

/**
 * 员工实体类:
 *       id     编号
 *       name   姓名
 *       gender 性别
 *       title  职位
 *       email
 *       salary 薪水
 */
public class Employee {

    private int id;
    private String name;
    private String gender;
    private String title;
    private String email;
    private String salary;

    public Employee() {

    }

    @Override
    public String toString() {
        return "Employee{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", gender='" + gender + '\'' +
                ", title='" + title + '\'' +
                ", email='" + email + '\'' +
                ", salary='" + salary + '\'' +
                '}';
    }

    public Employee(int id, String name, String gender, String title, String email, String salary) {
        this.id = id;
        this.name = name;
        this.gender = gender;
        this.title = title;
        this.email = email;
        this.salary = salary;
    }

    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 String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getSalary() {
        return salary;
    }

    public void setSalary(String salary) {
        this.salary = salary;
    }

}

2.写PageBean实体类,存放每页数据的实体类

对于分页显示的数据,我们可以进行-------->
“首页”,“上一页”,“下一页”,“尾页”,“每页显示的记录条数”,“跳转到第几页”,“当前页”
这7个参数的改变,但是实际情况真正变化的只有三个,也就是
当前页”,“每页显示的记录数”,“跳转到第几页”,其他参数都是围绕这三个变参进行的
比如-------->
首页,固定了就是1
上一页,就是当前页-1 (我没判断处理)
下一页,当前页+1 (我没判断处理)
尾页,就是总记录数除以每页显示的记录数
所以,真正在变化的只有3个参数

2.1写出PageBean实体类

package wh.entity;

import java.util.List;

/**
 * 分页对象,用于存储当前页分页相关的数据
 *  对于 "首页,上一页,下一页,尾页 "都是可以直接本事获取出
 * @author wh
 */
public class PageBean {
    /**当前页数据*/
    List<Employee> data;
    /**首页*/
    int firstPage;
    /**上一页*/
    int prePage;
    /**下一页*/
    int nextPage;
    /**尾页,也是总页数*/
    int totalPage;

    /**当前页*/
    int currentPage;
    /**每页显示记录数*/
    int pageSize;
    /**总记录数*/
    int totalCount;

    public List<Employee> getData() {
        return data;
    }

    public void setData(List<Employee> data) {
        this.data = data;
    }

    /**
     * 计算首页
     *  写死了就是1
     * @return
     */
    public int getFirstPage() {
        return 1;
    }

    public void setFirstPage(int firstPage) {
        this.firstPage = firstPage;
    }

    /**
     * 上一页
     *   算法:如果当前页为1,那么上一页就是当前页;否则就当前页-1
     * @return
     *
     */
    public int getPrePage() {
        return this.getCurrentPage()==this.getFirstPage()?1:
                this.getCurrentPage()-1;
    }

    public void setPrePage(int prePage) {
        this.prePage = prePage;
    }

    /**
     * 下一页
     *  算法:若当前页是末页,则为末页;否则为当前页+1
     * @return
     */
    public int getNextPage() {
        return this.getCurrentPage()==this.getTotalPage()?this
                .getTotalPage():
                this.getCurrentPage()+1;
    }

    public void setNextPage(int nextPage) {
        this.nextPage = nextPage;
    }

    /**
     * 计算末页:
     *     算法:如果总记录数%每页显示记录数==0
     *          如果不能整数,等于总记录数/每页显示记录数+1
     * @return
     */
    public int getTotalPage() {
        return this.getTotalCount()%this.getPageSize()==0?this.getTotalCount()/this.getPageSize()
                :
                this.getTotalCount()/this.getPageSize()+1;
    }

    public void setTotalPage(int totalPage) {
        this.totalPage = totalPage;
    }

    public int getCurrentPage() {
        return currentPage;
    }

    public void setCurrentPage(int currentPage) {
        this.currentPage = currentPage;
    }

    public int getTotalCount() {
        return totalCount;
    }

    public void setTotalCount(int totalCount) {
        this.totalCount = totalCount;
    }

    public int getPageSize() {
        return pageSize;
    }

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

上面的代码对于上一页,下一页做了判断,可以参考

4.service层,dao层的实现

4.1 dao层的接口,就两个方法
在这里插入图片描述
4.2 dao层的实现类

package wh.dao.imple;

import wh.dao.EmpDao;
import wh.entity.Employee;
import wh.util.C3P0Util;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;

import java.sql.SQLException;
import java.util.List;

/**
 * 员工接口的实现类
 * @author wh
 *
 */
public class EmpDaoImple implements EmpDao {
    /**
     * 提供一个查询当前员工数据的方法
     */
    @Override
    public List<Employee> queryData(int currentPage,int pageSize ) {
        /**
         * 总结 select * from employee limit (当前页页码-1)*每页显示的记录条数,每页显示的记录条数;
         */
        //创建QueryRunner对象,传入数据源
        QueryRunner qr = new QueryRunner(C3P0Util.getDataSource());
        String sql="select * from employee limit ?,?";
        /**
        String sql="select * from employee limit (当前页页码-1)*每页显示的记录条数,每页显示的记录条数;\n";
         */
        //起始行
        int startNo = (currentPage-1)*pageSize;
        List<Employee> list=null;
        //todo 使用JavaBean对象的list集合的实现类 BeanListHandler类封装
        try {
            list=qr.query(sql, new BeanListHandler<Employee>(Employee.class), new Object[]{startNo,pageSize});
            return list;
        } catch (SQLException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }
    /**
     * 提供一个查询总记录数的方法
     *
     */
    @Override
    public int queryCount() {
        //获取QueryRunner对象,传入数据源
        QueryRunner qr = new QueryRunner(C3P0Util.getDataSource());
        String sql="select count(*) from employee";
        try {
            Long count = (long) qr.query(sql, new ScalarHandler());
            //将long的类型转成int类型
            return count.intValue();
        } catch (SQLException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

    public static void main(String[] args) {
        List<Employee>list = new EmpDaoImple().queryData(4, 2);
       for (Employee employee:list){
           System.out.println(employee);
       }
        System.out.println(new EmpDaoImple().queryCount());
    }

}

分页的核心:
select * from employee limit (当前页页码-1)*每页显示的记录条数,每页显示的记录条数

4.3 service层的接口
在这里插入图片描述
4.4 service的实现类
在这里插入图片描述

package wh.service.imple;

import wh.dao.EmpDao;
import wh.dao.imple.EmpDaoImple;
import wh.entity.Employee;
import wh.entity.PageBean;
import wh.service.EmpService;

import java.util.List;

public class EmpServiceImple implements EmpService {
    /**
     *
     * 提供一个封装好的 PageBean对象的方法
     *
     *传入当前页的页数,和每页的大小
     * @return
     *
     */
    @Override
    public PageBean queryPageBean(String currentPage,int pageSize) {

        //1)封装PageBean对象
        PageBean pageBean = new PageBean();
        //todo 显示当前页数据应该在dao层实现
        //1.2)记录当前页的数据
        pageBean.setCurrentPage(Integer.parseInt(currentPage));
        //得到dao层的实现类对象,操作方法
        EmpDao empDao = new EmpDaoImple();
        //1.3)显示当前页数据
        //前提:准备好总记录数和每页大小
        //获取数据库的总记录数
        int totalCount=empDao.queryCount();
        pageBean.setTotalCount(totalCount);
        //每页的数据大小
        pageBean.setPageSize(pageSize);
        List<Employee> list = empDao.queryData(pageBean.getCurrentPage()    , pageBean.getPageSize());
        //1.4)添加到PageBean对象中
        pageBean.setData(list);
        return pageBean;
    }
}

5. web层的分发转向

在这里插入图片描述

package wh.web;

import wh.entity.PageBean;
import wh.service.EmpService;
import wh.service.imple.EmpServiceImple;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * Web层:
 *    接收用户输入的参数,第几页
 *    调用业务逻辑的方法,获取结果
 *    将结果转发到jsp界面显示
 * @author wh
 *
 */
@WebServlet(name = "ListEmpServlet",urlPatterns = ("/listEmpServlet"))
public class ListEmpServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
         doGet(request, response);
    }
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //三步
        request.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        //从用户参数获取当前页数据(currentPage)
        String currentPage = request.getParameter("currentPage");
        if (currentPage==null||currentPage.equals("")){
            //如果第一次访问,没有传递currentPage参数,则当前页为1
            currentPage="1";
        }
        //接收用户输入的每页显示数据的记录数
        String pageSize = request.getParameter("pageSize");
        //如果没有传递过来,设置一个默认值为2
        //细节:当点击下一页或者别的,会导致pageSize丢失了,应该要带回去
        if (pageSize==null||pageSize.equals("")){
            //设置pageSize的默认值是2
            pageSize="2";
        }

        //1)在service层调用获取PageBean对象的方法
        EmpService empService = new EmpServiceImple();
        //只需要传入一个currentPage(当前页数)即可
        PageBean pageBean = empService.queryPageBean(currentPage,Integer.parseInt(pageSize));
        //2)把PageBean对象放到域中
        request.setAttribute("pageBean", pageBean);
        //3)转发
        request.getRequestDispatcher("/listEmp.jsp").forward(request, response);

    }
}

转发到listEmp.jsp中

6. jsp文件负责显示结果

在这里插入图片描述

<%--
  Created by IntelliJ IDEA.
  User: ASUS
  Date: 2019/4/24
  Time: 9:31
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%-- 导入核心标签库 --%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title>显示结果</title>
</head>
<body>
<table border="1" align="center" width="=850px">
    <tr>
        <th>编号</th>
        <th>姓名</th>
        <th>性别</th>
        <th>职位</th>
        <th>邮箱</th>
        <th>薪水</th>
    </tr>
    <%-- 遍历域对象中pageBean中的list集合,也就是字段data --%>
    <%-- forEach遍历标签 --%>
    <c:forEach items="${pageBean.data}" var="emp">
        <tr>
            <td>${emp.id}</td>
            <td>${emp.name}</td>
            <td>${emp.gender}</td>
            <td>${emp.title}</td>
            <td>${emp.email}</td>
            <td>${emp.salary}</td>
        </tr>
    </c:forEach>
    <tr>
        <%--
        //todo 需求1:
        1)如果当前页是首页,就不能点击上一页和首页,否则就可以点击
        2)如果当前页是末页,就不能点击下一页和末页,否则就可以点击
        --%>
        <td align="center" colspan="6">
       <c:choose>
          <c:when test="${pageBean.currentPage==pageBean.firstPage}">
              首页&nbsp;
              上一页
          </c:when>
           <c:otherwise>
               <a href="${pageContext.request.contextPath}/listEmpServlet?currentPage=${pageBean.firstPage}&pageSize=${pageBean.pageSize}">首页&nbsp;</a>
               <a href="${pageContext.request.contextPath}/listEmpServlet?currentPage=${pageBean.prePage}&pageSize=${pageBean.pageSize}">上一页&nbsp;</a>
           </c:otherwise>
       </c:choose>
       <c:choose>
           <c:when test="${pageBean.currentPage==pageBean.totalPage}">
              下一页&nbsp;
               尾页
           </c:when>
           <c:otherwise>
               <a href="${pageContext.request.contextPath}/listEmpServlet?currentPage=${pageBean.nextPage}&pageSize=${pageBean.pageSize}">
                   下一页&nbsp;
               </a>
               <a href="${pageContext.request.contextPath}/listEmpServlet?currentPage=${pageBean.totalPage}&pageSize=${pageBean.pageSize}">               尾页&nbsp;</a>
           </c:otherwise>
       </c:choose>
            当前页为第${pageBean.currentPage}页/共${pageBean.totalPage}页
            总记录数是${pageBean.totalCount}条/
            <%--
            //todo 需求2
             用户输入每页显示数据的大小
            当输入完,焦点一释放就获取它的值使用js的onblur实现
            --%>
            每页显示<input type="text" id="pageSize" style="width: 25px" value="${pageBean.pageSize}" onblur="changePageSize()" >条
        <%--
         //todo 需求3:
          跳转到第几页
          分析:将它设计成一个下拉的列表供选择第几页
        --%>
        跳转到第<input type="text" id="currentPage" size="2"
                   value="${pageBean.currentPage}" onblur="changePage()">页
        </td>
    </tr>
</table>
</body>
<script type="text/javascript">
 /* 改变每页显示的记录数*/
    function changePageSize(){
        //1.得到用户输入的数据
        var pageSize = document.getElementById("pageSize").value;
        //2.处理用户输出的数据
        //判断规则:只能输入1-2位的数字
        var reg=/^[1-9][0-9]?$/; //?表示0-1个
        if (!reg.test(pageSize)){
           alert("只能输入1-2位的数字!");
           return;
        }
        //2.请求ListEmpServlet类,同时发送参数pageSize
        var url="${pageContext.request.contextPath}/listEmpServlet?pageSize="+pageSize;
        //请求一个地址
        window.location.href=url;
    }

    /* 跳转指定的页数的页面 */
    function changePage() {
        /*获取用户输入的数据*/
        var currentPage = document.getElementById("currentPage").value;
        var reg=/^[1-9][0-9]?$/;
        if(!reg.test(currentPage)){
            alert("只能输入1-2位数字!")
            return;
        }
        /* 如果输入的数字大于了最大页数,那么提示*/
        var totalPage="${pageBean.totalPage}";
        if(currentPage>totalPage){
            alert("已经超过了总页数!");
            return;
        }
        var url="${pageContext.request.contextPath}/listEmpServlet?currentPage="+currentPage+"&pageSize=${pageBean.pageSize}";
        window.location.href=url;
    }
</script>
</html>

1.使用到了forEach标签遍历结果集,因为结果集是一个List集合
里面存放的就是Employee实体类
通过.获取里面的字段值 ,例如${emp.id},emp只是一个别名,就是这个List集合的别名
直接forEach展示完了当前页的数据
2.
后面进行了判断,是否显示链接使用户点击,第一页的话,首页就失效!
<c:chooes>,<c:when>,<c:otherwise>这3个标签经常是一起使用的
用于判断处理,好比 if… else…

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值