前言:
最近做学校的课程设计用到了分页这个功能,分页功能基本任何一个网站都会用到,以前一直用Mybatsi的PageHelper,吃快餐吃的都快忘了怎么拿筷子...(插件和框架虽好,不要过度依赖...有时候还是原生的好)
于是今天就用最基础的JDBC实现了一个分页功能
原理:
说到分页功能,可能很多人没接触过,大体分析一下,分页这个功能其实看起来复杂,实际也没这么复杂,首先来看一下分页查询sql语句怎么定义的
select * from 表 limit 开始索引, 查询数量
比如传递的是0,5就是查询从0开始的五条记录,因此分页功能底层支持也就明确了,首先你要明确查询数量,也就是当前页面最大记录数,其次你需要知道从第几条记录开始查
比如我要查第二页,一页包含10条记录,那么就应该从11开始查询,查询数量应该为10,也就是sql语句如下
select * from 表 limit 11, 10
然后得到这些数据应该怎么发送到前端页面?直接添加到List然后通过list发送吗?那如果我怎么知道当前网站一共有几页,以及当前页码,前一页和后一页,这些数据都应该一次性发送到前端,然后前端分析并解析这些数据,对网页进行调整,比如动态添加页码等
因此需要封装一个类,将这些信息封装到这个类,然后直接发送这个类
封装页面类:
通过需求可以知道这个类主要包含的字段,首先要保存数据,分页数据,可以使用List类型,然后是当前页面的相关属性,当前页面,总页码数,前一页,后一页等等,封装类如下
由于页面存放的数据是不同类型,因此直接将这个类设置为泛型类,不同类型分页数据都可以直接使用
package util;
import java.util.List;
/**
* 页面工具类
*
* @author rambler
* @since 2019年7月2日 09:46:16
*/
public class PageBean<T> {
//页面信息
private Integer currentPage; //当前页面(前端选择的页码数,默认为1)
private Integer totalRecord; //总记录数(从数据库中查询出来的总记录数)
private Integer pageSize; //页面大小(当前页面最大记录数,一页包含几条数据)
private Integer totalPage; //总页面数(一共需要分几页-->总记录数/页面大小)
private Integer startIndex; //开始索引
//翻页
private Integer previousPage; //上一页(上一页页码)
private Integer nextPage; //下一页(下一页页码)
//用来存数据
private List<T> data;//存放具体的数据
//构造一个页面大小为pageSize,页码为pageNum,总记录数为totalRecord的页面
public PageBean(Integer pageNum, Integer pageSize, Integer totalRecord) {
this.pageSize = pageSize;
this.totalRecord = totalRecord;
//计算总页数,分成能被整除和不能被整除两种情况
//第一种情况,能被整除,比如一共有15条记录,页面大小为5,正好分3页
if (totalRecord % pageSize == 0) {
totalPage = totalRecord / pageSize;
}
//第二种情况,不能被整除,比如一共16条记录,页面大小为5,应该分16/3+1=4页
else {
totalPage = (totalRecord / pageSize) + 1;
}
//当前页面容错处理
if (pageNum > totalPage) {
currentPage = totalPage;
} else if (pageNum < 1) {
currentPage = 1;
} else {
this.currentPage = pageNum;
}
//起始索引,比如第一页,页面大小为5,则第一页就应该是1-5,同理,第二页就应该是6-10,依次类推
this.startIndex = (currentPage - 1) * pageSize;
//前一页后一页设置,根据当前页面进行讨论
//当前页面不是第一页也不是最后一页,正常赋值
if (pageNum > 1 && pageNum < totalPage) {
previousPage = pageNum - 1;
nextPage = pageNum + 1;
} else if (pageNum <= 1) {
previousPage = 1;
nextPage = pageNum + 1;
} else {
previousPage = pageNum - 1;
nextPage = totalPage;
}
}
public Integer getCurrentPage() {
return currentPage;
}
public void setCurrentPage(Integer currentPage) {
this.currentPage = currentPage;
}
public Integer getTotalRecord() {
return totalRecord;
}
public void setTotalRecord(Integer totalRecord) {
this.totalRecord = totalRecord;
}
public Integer getPageSize() {
return pageSize;
}
public void setPageSize(Integer pageSize) {
this.pageSize = pageSize;
}
public Integer getTotalPage() {
return totalPage;
}
public void setTotalPage(Integer totalPage) {
this.totalPage = totalPage;
}
public Integer getStartIndex() {
return startIndex;
}
public void setStartIndex(Integer startIndex) {
this.startIndex = startIndex;
}
public Integer getPreviousPage() {
return previousPage;
}
public void setPreviousPage(Integer previousPage) {
this.previousPage = previousPage;
}
public Integer getNextPage() {
return nextPage;
}
public void setNextPage(Integer nextPage) {
this.nextPage = nextPage;
}
public List<T> getData() {
return data;
}
public void setData(List<T> data) {
this.data = data;
}
@Override
public String toString() {
return "PageBean{" +
"当前页面:" + currentPage +
", 总记录数:" + totalRecord +
", 页面大小:" + pageSize +
", 总页码数:" + totalPage +
", 开始索引:" + startIndex +
", 上一页:" + previousPage +
", 下一页" + nextPage +
", 数据:" + data +
'}';
}
}
测试:
然后进行测试,在数据库建一个基本的用户表,包含字段username和password
然后插入几条数据
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`username` varchar(255) CHARACTER SET utf8 COLLATE utf8_croatian_ci NULL DEFAULT NULL,
`password` varchar(255) CHARACTER SET utf8 COLLATE utf8_croatian_ci NULL DEFAULT NULL
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_croatian_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES ('zhanyi', '123456');
INSERT INTO `user` VALUES ('caiwei', '123456');
INSERT INTO `user` VALUES ('苏浩', '123');
INSERT INTO `user` VALUES ('展一', '123456');
INSERT INTO `user` VALUES ('ram', '123456');
INSERT INTO `user` VALUES ('张三', '111');
INSERT INTO `user` VALUES ('李四', '1155');
INSERT INTO `user` VALUES ('王五', '1111');
INSERT INTO `user` VALUES ('苹果', '111');
INSERT INTO `user` VALUES ('梨', '555');
INSERT INTO `user` VALUES ('荔枝', '554');
INSERT INTO `user` VALUES ('西瓜', '987');
INSERT INTO `user` VALUES ('风扇', '546');
然后编写一个工具类,由于业务层比较简单,因此忽略dao层,直接在工具类中完成查询...
package util;
import bean.User;
import java.sql.*;
import java.util.LinkedList;
import java.util.List;
public class DBUtil {
private static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
private static final String DB_URL = "jdbc:mysql://localhost:3306/login?useUnicode=true&characterEncoding=utf-8&useSSL=false";
private static final String USERNAME = "root";
private static final String PASSWORD = "你的数据库密码";
private static Connection getConnection() {
try {
Class.forName(JDBC_DRIVER).newInstance();
return DriverManager.getConnection(DB_URL, USERNAME, PASSWORD);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static List<User> getUserList(Integer startIndex, Integer count) {
LinkedList<User> list = new LinkedList<>();
Connection connection = null;
PreparedStatement preparedStatement = null;
try {
connection = getConnection();
String sql = "select * from user limit ?,?";
preparedStatement = connection.prepareStatement(sql);
preparedStatement.setObject(1, startIndex);
preparedStatement.setObject(2, count);
ResultSet rs = preparedStatement.executeQuery();
while (rs.next()) {
String username = rs.getString("username");
String password = rs.getString("password");
User user = new User(username, password);
list.add(user);
}
connection.close();
preparedStatement.close();
return list;
} catch (Exception e) {
System.out.println("登录异常");
e.printStackTrace();
}
return null;
}
}
最后是测试类
import bean.User;
import util.DBUtil;
import util.PageBean;
public class Main {
public static void main(String[] args) {
PageBean<User> pageBean = new PageBean<>(3, 5, 32);
pageBean.setData(DBUtil.getUserList(pageBean.getStartIndex(), pageBean.getPageSize()));
System.out.println(pageBean.toString());
}
}
运行结果:
PageBean{当前页面:3, 总记录数:32, 页面大小:5, 总页码数:7, 开始索引:10, 上一页:2, 下一页4, 数据:[User{username='荔枝', password='554'}, User{username='西瓜', password='987'}, User{username='风扇', password='546'}]}