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,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访问了,都是框架提供好一些方法自己直接配置就能用了
代码下载
需要下载这篇文章的项目的话,请访问该地址进行下载
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、修改项目的环境 -
如果是在不行,一个一个的写到你的空项目里没有出现创建错误或者环境错误