目录
使用工具:
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: 206647497@qq.com
* @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: 206647497@qq.com
* @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: 206647497@qq.com
* @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>
、
效果展示: