欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

jdbc+servlet+jsp来写个mysql分页案例

程序员文章站 2022-06-18 11:37:46
...

一、项目使用到的内容

jsp servlet bootstrap3 jdk6 tomcat6 jstl标签库 EL表达式语言 mysql 5.5 eclipse(Neon)

二、项目的目录结构

jdbc+servlet+jsp来写个mysql分页案例
第三方的架包文件
jdbc+servlet+jsp来写个mysql分页案例

三、主要的代码

  • 1、数据文件subwayinfo.sql
USE `test`;
DROP TABLE IF EXISTS `subwayinfo`;
CREATE TABLE `subwayinfo` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '编号',
  `subwayname` varchar(50) NOT NULL COMMENT '线路名称',
  `start_station` varchar(50) NOT NULL COMMENT '始发站',
  `end_station` varchar(50) NOT NULL COMMENT '终点站',
  `station_num` int(10) NOT NULL COMMENT '途径站点数',
  `start_time` varchar(50) DEFAULT '--' COMMENT '发车时间',
  `price` int(11) DEFAULT '2' COMMENT '票价',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;

insert  into `subwayinfo`(`id`,`subwayname`,`start_station`,`end_station`,`station_num`,`start_time`,`price`) values (1,'1号线','苹果园','四惠东',23,'5:10',2);
insert  into `subwayinfo`(`id`,`subwayname`,`start_station`,`end_station`,`station_num`,`start_time`,`price`) values (2,'2号线','西直门','西直门',18,'5:09',2);
insert  into `subwayinfo`(`id`,`subwayname`,`start_station`,`end_station`,`station_num`,`start_time`,`price`) values (3,'4号线','安河桥北','公益西桥',24,'5:00',2);
insert  into `subwayinfo`(`id`,`subwayname`,`start_station`,`end_station`,`station_num`,`start_time`,`price`) values (4,'5号线','天通苑北','安家庄',23,'4:50',2);
insert  into `subwayinfo`(`id`,`subwayname`,`start_station`,`end_station`,`station_num`,`start_time`,`price`) values (5,'8号线','北土城','回龙观东大街',10,'5:33',2);
insert  into `subwayinfo`(`id`,`subwayname`,`start_station`,`end_station`,`station_num`,`start_time`,`price`) values (6,'测试线路1','黄金口','汉口火车站',22,'5:00',2);
insert  into `subwayinfo`(`id`,`subwayname`,`start_station`,`end_station`,`station_num`,`start_time`,`price`) values (7,'1号线','苹果园','四惠东',23,'5:10',2);
insert  into `subwayinfo`(`id`,`subwayname`,`start_station`,`end_station`,`station_num`,`start_time`,`price`) values (8,'2号线','西直门','西直门',18,'5:09',2);
insert  into `subwayinfo`(`id`,`subwayname`,`start_station`,`end_station`,`station_num`,`start_time`,`price`) values (9,'4号线','安河桥北','公益西桥',24,'5:00',2);
insert  into `subwayinfo`(`id`,`subwayname`,`start_station`,`end_station`,`station_num`,`start_time`,`price`) values (10,'5号线','天通苑北','安家庄',23,'4:50',2);
insert  into `subwayinfo`(`id`,`subwayname`,`start_station`,`end_station`,`station_num`,`start_time`,`price`) values (11,'8号线','北土城','回龙观东大街',10,'5:33',2);
insert  into `subwayinfo`(`id`,`subwayname`,`start_station`,`end_station`,`station_num`,`start_time`,`price`) values (12,'测试线路1','黄金口','汉口火车站',22,'5:00',2);
insert  into `subwayinfo`(`id`,`subwayname`,`start_station`,`end_station`,`station_num`,`start_time`,`price`) values (13,'1号线','苹果园','四惠东',23,'5:10',2);
insert  into `subwayinfo`(`id`,`subwayname`,`start_station`,`end_station`,`station_num`,`start_time`,`price`) values (14,'2号线','西直门','西直门',18,'5:09',2);
insert  into `subwayinfo`(`id`,`subwayname`,`start_station`,`end_station`,`station_num`,`start_time`,`price`) values (15,'4号线','安河桥北','公益西桥',24,'5:00',2);
insert  into `subwayinfo`(`id`,`subwayname`,`start_station`,`end_station`,`station_num`,`start_time`,`price`) values (16,'5号线','天通苑北','安家庄',23,'4:50',2);
insert  into `subwayinfo`(`id`,`subwayname`,`start_station`,`end_station`,`station_num`,`start_time`,`price`) values (17,'8号线','北土城','回龙观东大街',10,'5:33',2);
insert  into `subwayinfo`(`id`,`subwayname`,`start_station`,`end_station`,`station_num`,`start_time`,`price`) values (18,'测试线路1','黄金口','汉口火车站',22,'5:00',2);
insert  into `subwayinfo`(`id`,`subwayname`,`start_station`,`end_station`,`station_num`,`start_time`,`price`) values (19,'1号线','苹果园','四惠东',23,'5:10',2);
insert  into `subwayinfo`(`id`,`subwayname`,`start_station`,`end_station`,`station_num`,`start_time`,`price`) values (20,'2号线','西直门','西直门',18,'5:09',2);
insert  into `subwayinfo`(`id`,`subwayname`,`start_station`,`end_station`,`station_num`,`start_time`,`price`) values (21,'4号线','安河桥北','公益西桥',24,'5:00',2);
insert  into `subwayinfo`(`id`,`subwayname`,`start_station`,`end_station`,`station_num`,`start_time`,`price`) values (22,'5号线','天通苑北','安家庄',23,'4:50',2);
insert  into `subwayinfo`(`id`,`subwayname`,`start_station`,`end_station`,`station_num`,`start_time`,`price`) values (23,'8号线','北土城','回龙观东大街',10,'5:33',2);
insert  into `subwayinfo`(`id`,`subwayname`,`start_station`,`end_station`,`station_num`,`start_time`,`price`) values (24,'测试线路1','黄金口','汉口火车站',22,'5:00',2);
insert  into `subwayinfo`(`id`,`subwayname`,`start_station`,`end_station`,`station_num`,`start_time`,`price`) values (25,'1号线','苹果园','四惠东',23,'5:10',2);
insert  into `subwayinfo`(`id`,`subwayname`,`start_station`,`end_station`,`station_num`,`start_time`,`price`) values (26,'2号线','西直门','西直门',18,'5:09',2);
insert  into `subwayinfo`(`id`,`subwayname`,`start_station`,`end_station`,`station_num`,`start_time`,`price`) values (27,'4号线','安河桥北','公益西桥',24,'5:00',2);
  • 2、bean包下的文件

第一个文件SubwayInfo.java

package top.linksinke.bean;

/**
 * subwayinfo表对应的实体类<br/>
 * create by LINKSINKE on 2020/3/11
 */
public class SubwayInfo implements java.io.Serializable {
	private static final long serialVersionUID = -8471088390616186369L;
	
	private Long id;// 线路编号
	private String subwayname;// 线路名称
	private String start_station; // 始发站
	private String end_station;// 终点站
	private Integer station_num;// 途径站点数
	private String start_time; // 发车时间
	private Double price;// 票价
	
	public SubwayInfo() { super();  }

	@Override
	public String toString() {
		return "SubwayInfo [id=" + id + ", subwayname=" + subwayname + ", start_station=" + start_station
				+ ", end_station=" + end_station + ", station_num=" + station_num + ", start_time=" + start_time
				+ ", price=" + price + "]";
	}

	public Long getId() { 	return id; }
	public void setId(Long id) { this.id = id; }
	public String getSubwayname() { 	return subwayname; }
	public void setSubwayname(String subwayname) { this.subwayname = subwayname; 	}
	public String getStart_station() { return start_station; 	}
	public void setStart_station(String start_station) { 	this.start_station = start_station; 	}
	public String getEnd_station() { 	return end_station; 	}
	public void setEnd_station(String end_station) { this.end_station = end_station; 	}
	public Integer getStation_num() { 	return station_num; }
	public void setStation_num(Integer station_num) { this.station_num = station_num; }
	public String getStart_time() { return start_time; 	}
	public void setStart_time(String start_time) { 	this.start_time = start_time; 	}
	public Double getPrice() { 	return price; }
	public void setPrice(Double price) { this.price = price; 	}
}

第二个文件PageInfo.java

package top.linksinke.bean;

/**
 * 分页信息实体类<br/>
 * create by LINKSINKE on 2020/3/11
 */
public class PageInfo {
	private Integer currentPage; // 当前是多少页
	private Integer startNo;// 起始条数
	private Integer endNo;// 结束条数
	private Integer backPageNo; // 上一页
	private Integer nextPageNo; // 下一页
	private Integer totalData; // 总的数据量
	private Integer totalPage; // 总的分页数量
	private Integer pageSize; // 每页显示多少条数据量

	public PageInfo() { super(); }
	/**
	 * 取得分页信息
	 * 
	 * @param currentNo
	 *            当前的页码
	 * @param totalData
	 *            总共的数据量
	 * @param pageSize
	 *            每页显示的数据量
	 */
	public PageInfo(Integer currentPage, Integer totalData, Integer pageSize) {
		super();
		this.currentPage = currentPage;
		this.totalData = totalData;
		this.pageSize = pageSize;
		/**
		 * 总的分页数量<br>
		 * 总的数据量除以每页显示的数量,如果结果不为0,就增加一页
		 */
		this.totalPage = totalData % pageSize == 0 ? totalData / pageSize : totalData / pageSize + 1;

		/**
		 * 每页最开始的一条数据<br>
		 * 例如:显示第一页,每页五条数据,那么语法是:limit 0,5<br>
		 * 显示第二页,每页五条数据,那么语法是: limit 5,10<br>
		 * 显示第三页,每页五条数据,那么语法是: limit 10,15<br>
		 * <p>
		 * 每一页显示的数量是一样的,即不会发生改变的<br>
		 * 而当前的页会发生改变,比如到第二页、第三页,其开始页的结果也会有所不同
		 * 可以看出每次翻一页就等于上一页的累计页面显示的数量
		 * </p>
		 */
		this.startNo = (currentPage - 1) * pageSize;

		/**
		 * 每页最后面的一条数据<br>
		 * 例如:显示第一页,每页五条数据,那么语法是:limit 0,5<br>
		 * 显示第二页,每页五条数据,那么语法是: limit 6,10<br>
		 * 显示第三页,每页五条数据,那么语法是: limit 10,15<br>
		 * 所以可以得到最后一条数据总是等于总数据量
		 */
		this.endNo = pageSize;
		/**
		 * 上一页<br>
		 * 假设当前页是小于-1或者是直接为1的,那么就让他等于1,要不然sql语法会发生错误
		 */
		this.backPageNo = currentPage <= 1 ? 1 : currentPage - 1;

		/**
		 * 下一页<br>
		 * 假设当前页没有超出了总的页面数据量,那么就让他继续当前页+1页,超出则等于总的页面数据量(注意判断的顺序)
		 */
		this.nextPageNo = currentPage < totalPage ?  currentPage + 1 : currentPage ;
	}

	@Override
	public String toString() {
		return "PageInfo [currentPage=" + currentPage + ", startNo=" + startNo + ", endNo=" + endNo + ", backPageNo="
				+ backPageNo + ", nextPageNo=" + nextPageNo + ", totalData=" + totalData + ", totalPage=" + totalPage
				+ ", pageSize=" + pageSize + "]";
	}

	public Integer getCurrentPage() { return currentPage; }
	public void setCurrentPage(Integer currentPage) { this.currentPage = currentPage; }
	public Integer getStartNo() { return startNo; }
	public void setStartNo(Integer startNo) { this.startNo = startNo; }
	public Integer getEndNo() { return endNo; }
	public void setEndNo(Integer endNo) { this.endNo = endNo; }
	public Integer getBackPageNo() { return backPageNo; }
	public void setBackPageNo(Integer backPageNo) { this.backPageNo = backPageNo; }
	public Integer getNextPageNo() { return nextPageNo; }
	public void setNextPageNo(Integer nextPageNo) { this.nextPageNo = nextPageNo; }
	public Integer getTotalData() { return totalData; }
	public void setTotalData(Integer totalData) { this.totalData = totalData; }
	public Integer getTotalPage() { return totalPage; }
	public void setTotalPage(Integer totalPage) { this.totalPage = totalPage; }
	public Integer getPageSize() { return pageSize; }
	public void setPageSize(Integer pageSize) { this.pageSize = pageSize; }
}
  • 3、dao包下的文件

SubwayInfoDao.java好像java面试题里有关于手敲一个jdbc连接并写个分页这样的题目,这个类应该算是核心的类吧。。。。。需要的可以直接借鉴该类

package top.linksinke.dao;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import top.linksinke.bean.PageInfo;
import top.linksinke.bean.SubwayInfo;

public class SubwayInfoDao {
	// mysql连接地址,数据库用户和密码
	private final String URL = "jdbc:mysql://localhost:3306/test";
	private final String USER = "root";
	private final String PASSWORD = "root";

	private Connection conn;// 连接
	private PreparedStatement ps; // sql执行者
	private ResultSet rs; // 返回的数据结果集

	/**
	 * @describe 关闭正在占用的资源
	 * @throws SQLException SQL语句语法存在错误
	 */
	public void close() throws SQLException {
		// 如果结果集在使用中
		if (rs != null) {
			rs.close();// 关闭结果集
		}
		// 如果执行者还在执行过程中
		if (ps != null) {
			ps.close();// 关闭执行者
		}
		// 如果连接状态是打开的情况
		if (conn != null) {
			conn.close();// 关闭连接
		}
	}

	/**
	 * 分页查询
	 * @param pageInfo
	 * @return SubwayInfo集合
	 */
	public List<SubwayInfo> searchByPage(PageInfo pageInfo) {
		Connection conn; // 连接源
		List<SubwayInfo> lis = new ArrayList<SubwayInfo>();
		try {
			// 1、加载mysql的驱动
			Class.forName("com.mysql.jdbc.Driver");

			// 2、获得连接源
			conn = DriverManager.getConnection(URL, USER, PASSWORD);

			// 3、获取sql执行者对象
			PreparedStatement ps = conn.prepareStatement("select * from subwayinfo limit ?,?");

			// 4、向sql中带参数的,没参数就不用准备下面的操作
			Object[] params = { pageInfo.getStartNo(), pageInfo.getEndNo() };
			for (int i = 0; i < params.length; i++) {
				ps.setObject(i + 1, params[i]);
			}

			// 5、执行者开始查询数据库数据并返回到结果集进行存储
			ResultSet rs = ps.executeQuery(); // 结果集对象

			// 6、读取数据
			while (rs.next()) { // rs如果存在下一条数据就开始循环
				// 将取出来的数据存放到集合中
				SubwayInfo subway = new SubwayInfo();
				subway.setId(rs.getLong("id"));
				subway.setSubwayname(rs.getString("subwayname"));
				subway.setStart_station(rs.getString("start_station"));
				subway.setEnd_station(rs.getString("end_station"));
				subway.setStation_num(rs.getInt("station_num"));
				subway.setStart_time(rs.getString("start_time"));
				subway.setPrice(rs.getDouble("price"));
				lis.add(subway);
			}

			// 7、返回最后的查询结果
			return lis;

		} catch (SQLException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 取得数据库的总数据量
	 * @return 总的数据量
	 */
	public Integer totalData() {
		Connection conn = null; // 连接源
		Integer count = null;
		try {
			Class.forName("com.mysql.jdbc.Driver");
			conn = DriverManager.getConnection(URL, USER, PASSWORD);
			PreparedStatement ps = conn.prepareStatement("select count(1) from subwayinfo");
			ResultSet rs = ps.executeQuery();
			if (rs.next()) {
				count = rs.getInt(1);
			}
			return count;
		} catch (SQLException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		return null;
	}

	// 方法测试
	public static void main(String[] args) {
		SubwayInfoDao dao = new SubwayInfoDao();
		System.out.println("总数据量" + dao.totalData());
		PageInfo pageInfo = new PageInfo(1, dao.totalData(), 5);
		List<SubwayInfo> info = dao.searchByPage(pageInfo);
		for (SubwayInfo subwayInfo : info) {
			System.out.println(subwayInfo);
		}
		System.out.println(pageInfo.toString());
	}
}

  • 4、servlet包下的文件

SubwayInfoServlet.java

package top.linksinke.servlet;

import java.io.IOException;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import top.linksinke.bean.PageInfo;
import top.linksinke.bean.SubwayInfo;
import top.linksinke.dao.SubwayInfoDao;

public class SubwayInfoServlet extends HttpServlet {
	@Override
	protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		HttpSession session = req.getSession();
		String page = req.getParameter("pageNo");
		// 要是找不到pageNo参数或者没有赋值就默认给值为1
		if (page == null || "".equals(page)) {
			page = "1";
		}
		// 取得pageInfo信息
		Integer currentPage = Integer.valueOf(page);
		 SubwayInfoDao subwayInfoDao = new SubwayInfoDao();
		Integer totalData = subwayInfoDao.totalData();
		Integer pageSize = 5;
		PageInfo pageInfo = new PageInfo(currentPage, totalData, pageSize);

		// 取得subwayInfo信息
		List<SubwayInfo> subwayinfo = subwayInfoDao.searchByPage(pageInfo);
		
		// pageInfo和subwayInfo信息都存储到session作用域中
		session.setAttribute("subwayinfo", subwayinfo);
		session.setAttribute("pageinfo", pageInfo);
		req.getRequestDispatcher("/index.jsp").forward(req, resp);// 转发
	}
}
  • 5、WebContent目录下的jsp文件

第一个chain.jsp,这个jsp的作用是,项目的发布访问后默认自行打开的页面,发送一个请求到servlet来加载数据结果并返回一个新的页面;

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<% response.sendRedirect(request.getContextPath() + "/display?pageNo=1"); %>

第二个index.jsp,这个页面是chain.jsp请求成功后跳转的页面。

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%
	String path = request.getContextPath();
	String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()
			+ path + "/";
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head lang="zh-Hans-cmn">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>mysql分页数据显示</title>
<link rel="stylesheet" type="text/css" href="assets/bootstrap-3.3.7.css">
<link rel="stylesheet" type="text/css" href="assets/bootstrap-theme-3.3.7.css">
</head>
<body>
	<div class="container">
		<div class="row">
			<div class="col-md-12 col-lg-12">
				<div class="page-header">
					<h1>mysql分页数据显示</h1>
				</div>
				<table>
					<tr>
						<th>线路编号</th>
						<th>线路名称</th>
						<th>始发站</th>
						<th>终点站</th>
						<th>途径站点数</th>
						<th>发车时间</th>
						<th>票价</th>
					</tr>
					<c:forEach var="info" items="${sessionScope.subwayinfo }">
						<tr>
							<td>${info.id }</td>
							<td>${info.subwayname}</td>
							<td>${info.start_station}</td>
							<td>${info.end_station}</td>
							<td>${info.station_num}</td>
							<td>${info.start_time}</td>
							<td>${info.price}</td>
						</tr>
					</c:forEach>
				</table>
			</div>
		</div>
		<hr>
		<nav aria-label="Page navigation">
		<p>
			共计<span style="color:red;">${sessionScope.pageinfo.totalData }</span>条数据,当前是第<span style="color:red;">${sessionScope.pageinfo.currentPage }</span></p>
		<ul class="pagination">
			<li><a href="<%=basePath%>display?pageNo=1" aria-label="首页">首页 </a></li>
			<li><a href="<%=basePath%>display?pageNo=${sessionScope.pageinfo.backPageNo }" aria-label="上一页">上一页</a></li>
			<li><a href="<%=basePath %>display?pageNo=${sessionScope.pageinfo.nextPageNo }" aria-label="下一页">下一页</a></li>
			<li><a href="<%=basePath %>display?pageNo=${sessionScope.pageinfo.totalPage }" aria-label="尾页"> 尾页</a></li>
		</ul>
		</nav>
	</div>
</body>
<script type="text/javascript" src="assets/jquery-1.12.4.js"></script>
<script type="text/javascript" src="assets/bootstrap-3.3.7.js"></script>
</html>
  • 6、最后一个是web.xml,配置的就是servlet请求的内容
<?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>paging_mysql</display-name>

  <servlet>
  	<servlet-name>subwayinfo</servlet-name>
  	<servlet-class>top.linksinke.servlet.SubwayInfoServlet</servlet-class>
  </servlet>
  <servlet-mapping>
  	<servlet-name>subwayinfo</servlet-name>
  	<url-pattern>/display</url-pattern>
  </servlet-mapping>
  
  <!-- 你说为什么默认就可以打开到chain.jsp呢,因为源头在这 -->
  <welcome-file-list>
    <welcome-file>chain.jsp</welcome-file>
  </welcome-file-list>
</web-app>

四、项目最终跑起来的效果

  • 先请求一下路径,看有没有问题
    比如:localhost:8080,看看tomcat是不是能正常访问;
    比如:localhost:8080/paging_mysql/display,看看不给pageNo参数能否正常打开index.jsp
    比如:localhost:8080/paging_mysql,看携带pageNo参数默认是不是打开index.jsp
    jdbc+servlet+jsp来写个mysql分页案例

  • 现在来看功能有没有问题吧
    jdbc+servlet+jsp来写个mysql分页案例
    功能基本没问题,翻上一页,下一页,首页,尾页都可以

总结

好长时间没有纯手工写jdbc访问了,都是框架提供好一些方法自己直接配置就能用了

代码下载

需要下载这篇文章的项目的话,请访问该地址进行下载
https://download.csdn.net/download/qq_29001539/12241984

下载后可能遇到的问题

  • 项目要怎么才能放入进来到我的ide里呢?
    你可以从头到尾的敲上一篇
    或者使用import菜单来导入项目
    1、找到import…,其他导入方式
    jdbc+servlet+jsp来写个mysql分页案例
    2、其他的选项不用,用这个选项,该选项可以复制项目到你工具的工作空间里,而不是引用该项目,好处是桌面上项目丢失了,该项目不会丢失
    jdbc+servlet+jsp来写个mysql分页案例
    3、导入项目
    jdbc+servlet+jsp来写个mysql分页案例

  • 数据库访问问题:
    mysql的版本过高,请更换mysql的驱动包
    mysql的连接发生错误,应该是mysql的root用户密码错误,或者你不是用的root用户等

  • 项目出现红叉叉:
    更换你工具里的环境(以eclipse项目为例)
    1、选择该项目,快捷键alt+enter,打开项目配置窗口
    jdbc+servlet+jsp来写个mysql分页案例
    2、修改项目的环境
    jdbc+servlet+jsp来写个mysql分页案例

  • 如果是在不行,一个一个的写到你的空项目里没有出现创建错误或者环境错误