java的分页原理详解
首先先创建一个Student实体类。
import java.io.Serializable;
import java.util.Map; public class Student implements Serializable {
//实现序列化接口,用于对象的持久化
private static final long serialVersionUID = -7476381137287496245L;
//学生记录id
private int id;
//学生姓名
private String stuName;
//学生年龄
private int age;
//学生性别
private int gender;
//学生住址
private String address;
//空构造器
public Student() {
super();
}
/**
* 构造器
* @param id 学生记录id
* @param stuName 学生姓名
* @param age 学生年龄
* @param gender 学生性别
* @param address 学生住址
*/
public Student(int id, String stuName, int age, int gender, String address) {
super();
this.id = id;
this.stuName = stuName;
this.age = age;
this.gender = gender;
this.address = address;
}
/**
* 该构造器用于将Map中的数据封装到Student类中,
* 在构造器中传入Map参数。
* @param map
*/
public Student(Map<String, Object> map){
this.id = (Integer)map.get("id");
this.stuName = (String)map.get("stu_name");
this.age = (Integer)map.get("age");
this.gender = (Integer)map.get("gender");
this.address = (String)map.get("address");
}
/*
* Getter Setter方法
*/
public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} public String getStuName() {
return stuName;
} public void setStuName(String stuName) {
this.stuName = stuName;
} public int getAge() {
return age;
} public void setAge(int age) {
this.age = age;
} public int getGender() {
return gender;
} public void setGender(int gender) {
this.gender = gender;
} public String getAddress() {
return address;
} public void setAddress(String address) {
this.address = address;
}
/*
* 重写toString方法
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return "Student [id=" + id + ", stuName=" + stuName + ", age=" + age
+ ", gender=" + gender + ", address=" + address + "]";
} }
创建Pager类
import java.io.Serializable;
import java.util.List; public class Pager<T> implements Serializable {
//实现序列化接口用于对象持久化
private static final long serialVersionUID = -8741766802354222579L;
// 每页显示多少条记录
private int pageSize;
//当前第几页数据
private int currentPage;
// 一共多少条记录
private int totalRecord;
// 一共多少页记录
private int totalPage;
//要显示的数据
private List<T> dataList;
//构造函数
public Pager(int pageNum, int pageSize, List<T> sourceList){
//如果数据源为空 跳出该构造方法
if(sourceList == null || sourceList.isEmpty()){
return;
} // 总记录条数等于数据源的长度
this.totalRecord = sourceList.size(); // 每页显示多少条记录
this.pageSize = pageSize; //获取最大页数 所有记录除以每页显示的条数
this.totalPage = this.totalRecord / this.pageSize;
if(this.totalRecord % this.pageSize !=0){
this.totalPage = this.totalPage + 1;
} // 当前第几页数据 如果参数pageNum超过最大页数
this.currentPage = this.totalPage < pageNum ? this.totalPage : pageNum; // 起始索引
int fromIndex = this.pageSize * (this.currentPage -1); // 结束索引
int toIndex = this.pageSize * this.currentPage > this.totalRecord ? this.totalRecord : this.pageSize * this.currentPage; this.dataList = sourceList.subList(fromIndex, toIndex);
}
//空构造器
public Pager(){ }
//构造器
public Pager(int pageSize, int currentPage, int totalRecord, int totalPage,
List<T> dataList) {
super();
this.pageSize = pageSize;
this.currentPage = currentPage;
this.totalRecord = totalRecord;
this.totalPage = totalPage;
this.dataList = dataList;
}
/*
* Getter 和 Setter 方法
*/
public int getPageSize() {
return pageSize;
} public void setPageSize(int pageSize) {
this.pageSize = pageSize;
} public int getCurrentPage() {
return currentPage;
} public void setCurrentPage(int currentPage) {
this.currentPage = currentPage;
} public int getTotalRecord() {
return totalRecord;
} public void setTotalRecord(int totalRecord) {
this.totalRecord = totalRecord;
} public int getTotalPage() {
return totalPage;
} public void setTotalPage(int totalPage) {
this.totalPage = totalPage;
} public List<T> getDataList() {
return dataList;
} public void setDataList(List<T> dataList) {
this.dataList = dataList;
} }
创建一个常量Constant类
public class Constant { /**
* 男性
*/
public static final int GENDER_MALE = 1; /**
* 女性
*/
public static final int GENDER_FEMALE = 2; /**
* 默认每页显示多少条记录
*/
public static final int DEFAULT_PAGE_SIZE = 5; /**
* 默认显示第几页记录
*/
public static final int DEFAULT_PAGE_NUM = 1; /**
* 默认学生性别
*/
public static final int DEFAULT_GENDER = 0;
}
创建StudentDAO类
public interface StudentDao { /**
* 根据查询条件,查询学生分页信息
*
* @param searchModel
* 封装查询条件
* @param pageNum
* 查询第几页数据
* @param pageSize
* 每页显示多少条记录
* @return 查询结果
*/
public Pager<Student> findStudent(Student searchModel, int pageNum,
int pageSize);
}
创建一个JdbcUtil工具类
public class JdbcUtil { // 表示定义数据库的用户名
private static String USERNAME ; // 定义数据库的密码
private static String PASSWORD; // 定义数据库的驱动信息
private static String DRIVER; // 定义访问数据库的地址
private static String URL; // 定义数据库的链接
private Connection connection; // 定义sql语句的执行对象
private PreparedStatement pstmt; // 定义查询返回的结果集合
private ResultSet resultSet; static{
//加载数据库配置信息,并给相关的属性赋值
loadConfig();
} /**
* 加载数据库配置信息,并给相关的属性赋值
* 从项目的jdbc.properties文件读取信息
* 然后设置连接参数
*/
public static void loadConfig() {
try {
InputStream inStream = JdbcUtil.class
.getResourceAsStream("/jdbc.properties");
Properties prop = new Properties();
prop.load(inStream);
USERNAME = prop.getProperty("jdbc.username");
PASSWORD = prop.getProperty("jdbc.password");
DRIVER= prop.getProperty("jdbc.driver");
URL = prop.getProperty("jdbc.url");
} catch (Exception e) {
throw new RuntimeException("读取数据库配置文件异常!", e);
}
} public JdbcUtil() { } /**
* 获取数据库连接
*
* @return 数据库连接
*/
public Connection getConnection() {
try {
Class.forName(DRIVER); // 注册驱动
connection = DriverManager.getConnection(URL, USERNAME, PASSWORD); // 获取连接
} catch (Exception e) {
throw new RuntimeException("get connection error!", e);
}
return connection;
} /**
* 执行更新操作
*
* @param sql
* sql语句
* @param params
* 执行参数
* @return 执行结果
* @throws SQLException
*/
public boolean updateByPreparedStatement(String sql, List<?> params)
throws SQLException {
boolean flag = false;
int result = -1;// 表示当用户执行添加删除和修改的时候所影响数据库的行数
pstmt = connection.prepareStatement(sql);
int index = 1;
// 填充sql语句中的占位符 依次填入预处理语句所需的参数
if (params != null && !params.isEmpty()) {
for (int i = 0; i < params.size(); i++) {
pstmt.setObject(index++, params.get(i));
}
}
result = pstmt.executeUpdate();
flag = result > 0 ? true : false;
return flag;
} /**
* 执行查询操作
*
* @param sql
* sql语句
* @param params
* 执行参数
* @return
* @throws SQLException
*/
public List<Map<String, Object>> findResult(String sql, List<?> params)
throws SQLException {
//创建泛型为Map类型的List
List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
//预处理语句参数索引
int index = 1;
pstmt = connection.prepareStatement(sql);
//依次填入参数
if (params != null && !params.isEmpty()) {
for (int i = 0; i < params.size(); i++) {
pstmt.setObject(index++, params.get(i));
}
}
//执行预处理语句 获得结果集
resultSet = pstmt.executeQuery();
//获取源数据
ResultSetMetaData metaData = resultSet.getMetaData();
//获取源数据的条数
int cols_len = metaData.getColumnCount();
//遍历resultSet将数据放入map中 再将map放入list中
while (resultSet.next()) {
Map<String, Object> map = new HashMap<String, Object>();
for (int i = 0; i < cols_len; i++) {
String cols_name = metaData.getColumnName(i + 1);
Object cols_value = resultSet.getObject(cols_name);
if (cols_value == null) {
cols_value = "";
}
map.put(cols_name, cols_value);
}
list.add(map);
}
return list;
} /**
* 释放资源
*/
public void releaseConn() {
if (resultSet != null) {
try {
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (pstmt != null) {
try {
pstmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (connection != null) {
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
} }
创建JdbcSqlStudentDaoImpl类
/**
* 使用mysql数据库limit关键字实现分页
*
*
*
*/
public class JdbcSqlStudentDaoImpl implements StudentDao {
//实现查询的方法
@Override
public Pager<Student> findStudent(Student searchModel, int pageNum,
int pageSize) {
//存放获取的数据
Pager<Student> result = null;
// 存放查询参数
List<Object> paramList = new ArrayList<Object>();
//获取查询参数Name
String stuName = searchModel.getStuName();
//获取查询参数gender
int gender = searchModel.getGender();
//创建查询语句
StringBuilder sql = new StringBuilder(
"select * from t_student where 1=1");
//得到所有的记录条数
StringBuilder countSql = new StringBuilder(
"select count(id) as totalRecord from t_student where 1=1 ");
//如果stuName存在且不为空的话 在两条sql语句后面加上查询条件
if (stuName != null && !stuName.equals("")) {
sql.append(" and stu_name like ?");
countSql.append(" and stu_name like ?");
//查询条件放入 查询参数集合中
paramList.add("%" + stuName + "%");
}
//如果gender的值 等于两个常量中的其中一个时
if (gender == Constant.GENDER_FEMALE || gender == Constant.GENDER_MALE) {
sql.append(" and gender = ?");
countSql.append(" and gender = ?");
paramList.add(gender);
} // 起始索引
int fromIndex = pageSize * (pageNum -1); // 使用limit关键字,实现分页
sql.append(" limit " + fromIndex + ", " + pageSize ); // 存放所有查询出的学生对象
List<Student> studentList = new ArrayList<Student>();
//创建JDBC工具类
JdbcUtil jdbcUtil = null;
try {
jdbcUtil = new JdbcUtil();
// 获取数据库链接
jdbcUtil.getConnection(); // 获取总记录数
List<Map<String, Object>> countResult = jdbcUtil.findResult(countSql.toString(), paramList);
//获取List中的第一个Map
Map<String, Object> countMap = countResult.get(0);
//获取Map中的键值为totalRecord的值
int totalRecord = ((Number)countMap.get("totalRecord")).intValue(); // 获取查询的学生记录
List<Map<String, Object>> studentResult = jdbcUtil.findResult(sql.toString(), paramList);
//将Map中的数据遍历出来封装成student类 再放入studentlist中去
if (studentResult != null) {
for (Map<String, Object> map : studentResult) {
Student s = new Student(map);
studentList.add(s);
}
} //获取总页数
int totalPage = totalRecord / pageSize;
if(totalRecord % pageSize !=0){
totalPage++;
} // 组装pager对象
result = new Pager<Student>(pageSize, pageNum,
totalRecord, totalPage, studentList); } catch (SQLException e) {
throw new RuntimeException("查询所有数据异常!", e);
} finally {
if (jdbcUtil != null) {
jdbcUtil.releaseConn(); // 一定要释放资源
}
}
return result;
} }
创建service类
public interface StudentService { /**
* 根据查询条件,查询学生分页信息
*
* @param searchModel
* 封装查询条件
* @param pageNum
* 查询第几页数据
* @param pageSize
* 每页显示多少条记录
* @return 查询结果
*/
public Pager<Student> findStudent(Student searchModel, int pageNum,
int pageSize);
}
创建Servlet类
public class JdbcSqlServlet extends HttpServlet { private static final long serialVersionUID = -318134993070614515L; private StudentService studentService = new JdbcSqlStudentServiceImpl(); public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException { doPost(request, response);
} public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 接收request里的参数
String stuName = request.getParameter("stuName"); //学生姓名 // 获取学生性别
//如果没有获取到就赋值为默认数值
int gender = Constant.DEFAULT_GENDER;
String genderStr = request.getParameter("gender");
//如果符合条件就转化为Int类型
if(genderStr!=null && !"".equals(genderStr.trim())){
gender = Integer.parseInt(genderStr);
} // 校验pageNum参数输入合法性
String pageNumStr = request.getParameter("pageNum");
//如果页码数不是数字的话
if(pageNumStr !=null && !StringUtil.isNum(pageNumStr)){
request.setAttribute("errorMsg", "参数传输错误");
request.getRequestDispatcher("jdbcSqlStudent.jsp").forward(request, response);
return;
}
//显示第几页数据
int pageNum = Constant.DEFAULT_PAGE_NUM;
//获取页码数
if(pageNumStr!=null && !"".equals(pageNumStr.trim())){
pageNum = Integer.parseInt(pageNumStr);
} int pageSize = Constant.DEFAULT_PAGE_SIZE; // 每页显示多少条记录
String pageSizeStr = request.getParameter("pageSize");
if(pageSizeStr!=null && !"".equals(pageSizeStr.trim())){
pageSize = Integer.parseInt(pageSizeStr);
} // 组装查询条件
Student searchModel = new Student();
searchModel.setStuName(stuName);
searchModel.setGender(gender); //调用service 获取查询结果
Pager<Student> result = studentService.findStudent(searchModel,
pageNum, pageSize); // 返回结果到页面
request.setAttribute("result", result);
request.setAttribute("stuName", stuName);
request.setAttribute("gender", gender); request.getRequestDispatcher("jdbcSqlStudent.jsp").forward(request, response);
} }
加上一个正则工具类用于判断输入的参数是否为数字
public class StringUtil { /**
* 校验字符串是否是大于0的数字
* @param string
* @return
*/
public static boolean isNum(String string){
Pattern pattern = Pattern.compile("[1-9]{1}\\d*");
Matcher matcher = pattern.matcher(string);
return matcher.matches();
}
}
java的分页原理详解的更多相关文章
- JAVA线程池原理详解二
Executor框架的两级调度模型 在HotSpot VM的模型中,JAVA线程被一对一映射为本地操作系统线程.JAVA线程启动时会创建一个本地操作系统线程,当JAVA线程终止时,对应的操作系统线程也 ...
- Java虚拟机工作原理详解 (一)
一.类加载器 首先来看一下java程序的执行过程. 从这个框图很容易大体上了解java程序工作原理.首先,你写好java代码,保存到硬盘当中.然后你在命令行中输入 javac YourClassNam ...
- Java虚拟机工作原理详解
原文地址:http://blog.csdn.net/bingduanlbd/article/details/8363734 一.类加载器 首先来看一下java程序的执行过程. 从这个框图很容易大体上了 ...
- [转]java虚拟机工作原理详解
一.类加载器 首先来看一下java程序的执行过程. 从这个框图很容易大体上了解java程序工作原理.首先,你写好java代码,保存到硬盘当中.然后你在命令行中输入 javac YourClassNam ...
- JAVA线程池原理详解一
线程池的优点 1.线程是稀缺资源,使用线程池可以减少创建和销毁线程的次数,每个工作线程都可以重复使用. 2.可以根据系统的承受能力,调整线程池中工作线程的数量,防止因为消耗过多内存导致服务器崩溃. 线 ...
- Java中多线程原理详解
Java是少数的集中支持多线程的语言之一,大多数的语言智能运行单独的一个程序块,无法同时运行不同的多个程序块,Java的多线程机制弥补了这个缺憾,它可以让不同的程序块一起运行,这样可以让程序运行更加顺 ...
- JAVA线程池原理详解(1)
线程池的优点 1.线程是稀缺资源,使用线程池可以减少创建和销毁线程的次数,每个工作线程都可以重复使用. 2.可以根据系统的承受能力,调整线程池中工作线程的数量,防止因为消耗过多内存导致服务器崩溃. 线 ...
- Java并发--ReentrantLock原理详解
ReentrantLock是什么? ReentrantLock重入锁,递归无阻塞的同步机制,实现了Lock接口: 能够对共享资源重复加锁,即当前线程获取该锁,再次获取不会被阻塞: 支持公平锁和非公平锁 ...
- Java虚拟机工作原理详解 ( 二 )
首先这里澄清两个概念:JVM实例和JVM执行引擎实例,JVM实例对应了一个独立运行的Java程序,而JVM执行引擎实例则对应了属于用户运行程序的线程:也就是JVM实例是进程级别,而执行引擎是线程级别的 ...
随机推荐
- 万答#12,MGR整个集群挂掉后,如何才能自动选主,不用手动干预
欢迎来到 GreatSQL社区分享的MySQL技术文章,如有疑问或想学习的内容,可以在下方评论区留言,看到后会进行解答 本文转载自微信公众号"老叶茶馆" MGR整个集群挂掉后,如能 ...
- 青峰Flutter视频播放软件
下载地址: https://github.com/patton88/peak_flutter_player/raw/master/peak_flutter_player_v1.1.5_release0 ...
- ASP.NET Core 5.0中的Host.CreateDefaultBuilder执行过程
通过Rider调试的方式看了下ASP.NET Core 5.0的Web API默认项目,重点关注Host.CreateDefaultBuilder(args)中的执行过程,主要包括主机配置.应用程 ...
- Luogu1088 火星人 (康托展开)
皮一波 #include <iostream> #include <cstdio> #include <cstring> #include <algorith ...
- ZOJ 3537 (凸包 + 区间DP)(UNFINISHED)
#include "Head.cpp" const int N = 10007; int n, m; struct Point{ int x,y; bool operator &l ...
- Java SE 14 新增特性
Java SE 14 新增特性 作者:Grey 原文地址:Java SE 14 新增特性 源码 源仓库: Github:java_new_features 镜像仓库: GitCode:java_new ...
- java基础———打印三角形
代码 public static void main(String[] args) { for (int i = 1; i <= 5; i++) { for (int j = 5; j > ...
- 配置IConfiguration
前言 配置是我们必不可少的功能,我们在开发中,经常会遇到需要获取配置信息的需求,那么如何才能优雅的获取配置信息? 我们希望新的配置: 支持强类型 配置变更后通知 学习难度低 快速入门 根据使用场景我们 ...
- c++的一些笔记
--const 的一些用法 1,修饰指针 const int *p=.... 可以改变指针所指的位置,但不能改变指向位置的值. 2,修饰变量 int const * p=.... 可以改变指向位 ...
- Jsoup爬取网上数据完成翻译
Jsoup使用 首先进入Jsoup下载jar包 然后打开IDEA创建一个普通的java项目 在项目结构里创建 lib 目录 但是我们这样并不能直接进行使用 需要添加路径 右键点击 然后添加路径 选择模 ...