Java Web实现分页查询

使用工具:

JavaJDK1.8
Tomcat 8.5.33
IDEA
MySQL5.6

使用Jar包:

  • c3p0-0.9.1.2.jar
  • commons-dbutils-1.4.jar
  • javax.annotation.jar
  • javax.ejb.jar
  • javax.jms.jar
  • javax.persistence.jar
  • javax.resource.jar
  • javax.servlet.jar
  • javax.servlet.jsp.jar
  • javax.transaction.jar
  • jstl-1.2.jar
  • mysql-connector-java-8.0.13.jar
  • junit-4.12.jar + hamcrest-core-1.3.jar 这个两个缺一不可 (junit-4.8.jar以上可以代替这两个jar包)

项目下载连接:

微云链接:https://share.weiyun.com/WA6AmSix

数据库表
CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=101 DEFAULT CHARSET=utf8;

实体类:

用户实体类:
public class User {
    private Integer id;
    private String name;
    private Integer age;

    public User() {
    }

    public User(Integer id, String name, Integer age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    public Integer getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
分页实例化:

定义5个属性:
Integer pageNum :用来记录当前页面的页码
Integer pageSize :可以自定义当前页面最大显示多少条数据
Long totalSize :记录数据库存储的数据总共多少条
Integer pageCount : 将数据库的 总数据量 除以 当前页面最大显示数据量 得到 数据可以分多少页
List<T> data:存放每一页要显示的数据

this.pageCount = (int)(this.totalSize%this.pageSize == 0 ?
                this.totalSize / this.pageSize:this.totalSize/this.pageSize + 1);

当总数据量 除以 当前页面显示的数据量 刚好等于 0时数据页面不再 + 1,
当总数据量 除以 当前页面显示的数据量 有余数时,数据页面 + 1(额外加一页显示剩余的数据)。

例如:有21条数据,每页显示10条数据,需要3页才能把全部的数据展示出来。
如果刚好20条数据,每页显示10条数据,2页刚好展示全部的数据。

import java.util.List;

/**
 * @Author ꧁ʚVVcatɞ꧂
 * @Date 2020/6/15 12:20 星期一
 * @PackageName io.vvcat.domain
 * @ClassName PageBean
 * @Email: [email protected]
 * @CSDN: https://blog.csdn.net/qq_44989881
 * @Blog: vvcat.io
 **/

public class PageBean<T> {
   
    private Integer pageNum;  // 第几页
   
    private Integer pageSize;  // 每页几条数据
    
    private Long totalSize;  // 总共多少条数据
   
    private Integer pageCount;   // 总共能分几页
    
    private List<T> data;   // 每页存储的数据

    public PageBean(Integer pageNum, Integer pageSize, Long totalSize, List<T> data){
        this.pageNum = pageNum;
        this.pageSize = pageSize;
        this.totalSize = totalSize;
        this.data = data;

        this.pageCount = (int)(this.totalSize%this.pageSize == 0 ?
                this.totalSize / this.pageSize:this.totalSize/this.pageSize + 1);
    }

    public Integer getPageNum() {
        return pageNum;
    }

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

    public Integer getPageSize() {
        return pageSize;
    }

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

    public Long getTotalSize() {
        return totalSize;
    }

    public void setTotalSize(Long totalSize) {
        this.totalSize = totalSize;
    }

    public Integer getPageCount() {
        return pageCount;
    }

    public void setPageCount(Integer pageCount) {
        this.pageCount = pageCount;
    }

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

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

 @Override
    public String toString() {
        return "PageBean{" +
                "pageNum=" + pageNum +
                ", pageSize=" + pageSize +
                ", totalSize=" + totalSize +
                ", pageCount=" + pageCount +
                ", data=" + data +
                '}';
    }

在Dao接口中定义2个方法:

接口:

findByPage方法:当前页面的页码 和 页面能显示的最大数据量 作为参数返回通过mysql处理 显示当前页面对应的数据。
getCount方法:统计数据库数据的总量。

import domain.User;
import java.util.List;

public interface UserDao {
    // 返回指定页面的数据
    List<User> findByPage(Integer pagNum, Integer pageSize);
    
    // 返回总的数据量
    long getCount();
}

实现Dao接口方法解析:

例如:
目前数据库数据:
在这里插入图片描述

调用findByPage方法

例如:
pageNum = 0; 从第几页开始显示
pageSize = 10; 显示10条数据

SELECT * 
FROM USER     
ORDER BY id  // 正序排列
LIMIT 0,10   // 数据库是从下标0 开始查找数据

在这里插入图片描述

参数:(pageNum-1) * pageSize
刚进入看到的页面为第一页,数据库LIMIT 是下标第0页开始查询,所以减去1。

getCount方法

统计数据库数据的总量。

例如:
在这里插入图片描述

import dao.UserDao;
import domain.User;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;
import utils.DruidSourceUtils;


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

/**
 * @Author ꧁ʚVVcatɞ꧂
 * @Date 2020/6/17 12:20 星期五
 * @PackageName io.vvcat.dao.impl
 * @ClassName UserDaoImpl 
 * @Email: [email protected]
 * @CSDN: https://blog.csdn.net/qq_44989881
 * @Blog: vvcat.io
 **/
 
public class UserDaoImpl implements UserDao {
    @Override
    public List<User> findByPage(Integer pageNum, Integer pageSize) {
        QueryRunner qr = new QueryRunner(DruidSourceUtils.getDataSource());
        try {
            return qr.query("select * from user order by id limit ?,?",
                    new BeanListHandler<User>(User.class), (pageNum-1)*pageSize, pageSize);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public long getCount() {
        QueryRunner qr = new QueryRunner(DruidSourceUtils.getDataSource());
        try {
            return qr.query("select count(*) from user", new ScalarHandler<>());
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return 0;
    }
    
}

service层:

接口:

PageBean findByPage(Integer pageNum, Integer pageSize)方法:
将pageNum; pageSize; totalSize; pageCount; data; 这些参数通过 PageBean 返回给jsp页面。

public interface UserService {
    PageBean<User> findByPage(Integer pageNum, Integer pageSize);
}

接口实现:
public class UserServiceImpl implements UserService {
    @Override
    public PageBean<User> findByPage(Integer pageNum, Integer pageSize) {
        UserDao studentDao = new UserDaoImpl();
        List<User> data = studentDao.findByPage(pageNum, pageSize);  // 根据条件获取数据库对应数据


        long totalSize = 0;
        totalSize = studentDao.getCount();  // 获取数据库可分多少页数据

        PageBean<User> pageBean = new PageBean<>(pageNum, pageSize, totalSize, data);  // 将以上2条方法封装在一起,返回给Servlet;

        if (pageNum > pageBean.getPageCount()){
            pageBean.setPageNum(pageBean.getPageCount());
        }
        return pageBean;


    }

工具类:


import com.mchange.v2.c3p0.ComboPooledDataSource;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class JDBCUtil {

    static ComboPooledDataSource dataSource = null;
    static{
        dataSource = new ComboPooledDataSource();
    }

    public static DataSource getDataSouce() {
        return dataSource;
    }
    /**
     * 获取连接对象
     * @return
     * @throws SQLException
     */
    public static Connection getConn() throws SQLException{
        return dataSource.getConnection();
    }

    /**
     * 释放资源
     * @param conn
     * @param st
     * @param rs
     */
    public static void release(Connection conn , Statement st , ResultSet rs){
        closeRs(rs);
        closeSt(st);
        closeConn(conn);
    }
    public static void release(Connection conn , Statement st){
        closeSt(st);
        closeConn(conn);
    }


    private static void closeRs(ResultSet rs){
        try {
            if(rs != null){
                rs.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally{
            rs = null;
        }
    }

    private static void closeSt(Statement st){
        try {
            if(st != null){
                st.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally{
            st = null;
        }
    }

    private static void closeConn(Connection conn){
        try {
            if(conn != null){
                conn.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally{
            conn = null;
        }
    }
}

Servlet:

import io.vvcat.been.PageBean;
import io.vvcat.been.User;
import io.vvcat.service.UserService;
import io.vvcat.service.impl.UserServiceImpl;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @Author ꧁ʚVVcatɞ꧂
 * @Date 2020/6/19 18:02 星期五
 * @ProjectName PageSelect
 * @PackageName io.vvcat.Servlet
 * @ClassName ServletListUser
 * @Email: [email protected]
 * @Blog: vvcat.io
 * @CSDN: https://blog.csdn.net/qq_44989881
 * @Version 1.0
 **/
public class ServletListUser extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String pageNum = request.getParameter("pageNum");   // 获取前端页面传过来的页码
        String pageSize = request.getParameter("pageSize");   // 获取前端页面显示的数据
        int pageN = 0;
        int pageS = 0;
        if (pageNum==null||pageNum.trim().length()==0){   // 当第一次打开页面时是没有页码的,数据为null需要为页码赋值
            pageN = 1;
        }else {
            pageN=Integer.parseInt(pageNum);       
            if (pageN<1){      // 如果请求的页面小于 1 那么就将 pageN 赋值为 1 ,限制上一页请求传递过来的值是一个负数
                pageN=1;
            }
        }
        if (pageSize==null||pageSize.trim().length()==0){     // 为页面显示的数据进行初始化
            pageS=10;    // 如果此处修改为 8,那么每页最多只会显示 8 条数据,设置为 5 ,那么每页最多只会显示 5 条数据
        }else {
            pageS=Integer.parseInt(pageSize);   
        }
        UserService userService = new UserServiceImpl(); //  调用UserService  服务 
        PageBean<User> pageBean = userService.findByPage(pageN, pageS);  // 获取页面获取的值传递到数据库,获取对应的数据。
        request.setAttribute("pageBean", pageBean);
        request.getRequestDispatcher("/user.jsp").forward(request, response);  // 处理完成后返回user.jsp页面进行数据渲染。
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}

web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
    <display-name>user</display-name>
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
        <!--<welcome-file>index.htm</welcome-file>-->
        <welcome-file>index.jsp</welcome-file>
        <welcome-file>default.html</welcome-file>
        <!--<welcome-file>default.htm</welcome-file>-->
        <welcome-file>default.jsp</welcome-file>
    </welcome-file-list>

    <servlet>
        <description></description>
        <display-name>ServletListUser</display-name>
        <servlet-name>ServletListUser</servlet-name>
        <servlet-class>io.vvcat.Servlet.ServletListUser</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>ServletListUser</servlet-name>
        <url-pattern>/ServletListUser</url-pattern>
    </servlet-mapping>

</web-app>

c3p0-config.xml

要对以下三条进行修改和确认

<property name="jdbcUrl">jdbc:mysql://localhost/studnets?serverTimezone=GMT%2B8</property>
<property name="user">root</property>
<property name="password">123456</property>
  • 设置 数据库连接地址 jdbcUrl
  • 设置 数据库的用户名 user
  • 设置 数据库密码 password

注: serverTimezone=GMT%2B8 防止在使用IDEA对高版本数据库连接时出现时区报错问题。

<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>

	<!-- default-config 默认的配置,  -->
  <default-config>
    <property name="driverClass">com.mysql.jdbc.Driver</property>
    <property name="jdbcUrl">jdbc:mysql://localhost/db?serverTimezone=GMT%2B8</property>
    <property name="user">root</property>
    <property name="password">123456</property>
    
    
    <property name="initialPoolSize">10</property>
    <property name="maxIdleTime">30</property>
    <property name="maxPoolSize">100</property>
    <property name="minPoolSize">10</property>
    <property name="maxStatements">200</property>
  </default-config>
  
   <!-- This app is massive! -->
  <named-config name="oracle"> 
    <property name="acquireIncrement">50</property>
    <property name="initialPoolSize">100</property>
    <property name="minPoolSize">50</property>
    <property name="maxPoolSize">1000</property>

    <!-- intergalactoApp adopts a different approach to configuring statement caching -->
    <property name="maxStatements">0</property> 
    <property name="maxStatementsPerConnection">5</property>

    <!-- he's important, but there's only one of him -->
    <user-overrides user="master-of-the-universe"> 
      <property name="acquireIncrement">1</property>
      <property name="initialPoolSize">1</property>
      <property name="minPoolSize">1</property>
      <property name="maxPoolSize">5</property>
      <property name="maxStatementsPerConnection">50</property>
    </user-overrides>
  </named-config>

 
</c3p0-config>
	

信息展示页面:

首页:第一页对应页码设置为1,每次点击首页,将1传递到后台,进行查询数据。
上一页:点击上一页,会获取当前页码 - 1,传递到后台获取,上一页的数据。
下一页:点击下一页,会获取当前页码 + 1,传递到后台获取,下一页的数据。
尾页:将总共可分的页数(即最后一页),传递到后台,显示最后一页的数据。

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <table border="1" cellspacing="0" cellpadding="10" width="500" height="250" align="center">
        <tr>
            <td>学号</td>
            <td>姓名</td>
            <td>年龄</td>
        </tr>
        <c:forEach items="${pageBean.data}" var="user">
            <tr>
                <td>${user.id}</td>
                <td>${user.name}</td>
                <td>${user.age}</td>
            </tr>
        </c:forEach>
    </table>
    <div align="center">
        <a href="${pageContext.request.contextPath}/ServletListUser?pageNum=1&pageSize=${pageBean.pageSize}">首页</a>
        <a href="${pageContext.request.contextPath}/ServletListUser?pageNum=${pageBean.pageNum-1}&pageSize=${pageBean.pageSize}">上一页</a>
        <a href="${pageContext.request.contextPath}/ServletListUser?pageNum=${pageBean.pageNum+1}&pageSize=${pageBean.pageSize}">下一页</a>
        <a href="${pageContext.request.contextPath}/ServletListUser?pageNum=${pageBean.pageCount}&pageSize=${pageBean.pageSize}">尾页</a>
    </div>
</body>
</html>

效果展示:

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

猜你喜欢

转载自blog.csdn.net/qq_44989881/article/details/106852649