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

一、项目使用到的内容

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

二、项目的目录结构

在这里插入图片描述
第三方的架包文件
在这里插入图片描述

三、主要的代码

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

		/**
		 * 每页最后面的一条数据<br>
		 * 例如:显示第一页,每页五条数据,那么语法是:limit 0,5<br>
		 * 显示第二页,每页五条数据,那么语法是: limit 6,5<br>
		 * 显示第三页,每页五条数据,那么语法是: limit 10,5<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访问了,都是框架提供好一些方法自己直接配置就能用了

代码下载

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

下载后可能遇到的问题

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

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

  • 项目出现红叉叉:
    更换你工具里的环境(以eclipse项目为例)
    1、选择该项目,快捷键alt+enter,打开项目配置窗口
    在这里插入图片描述
    2、修改项目的环境
    在这里插入图片描述

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

发布了68 篇原创文章 · 获赞 12 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_29001539/article/details/104800923