首先先创建一个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的分页原理详解的更多相关文章

  1. JAVA线程池原理详解二

    Executor框架的两级调度模型 在HotSpot VM的模型中,JAVA线程被一对一映射为本地操作系统线程.JAVA线程启动时会创建一个本地操作系统线程,当JAVA线程终止时,对应的操作系统线程也 ...

  2. Java虚拟机工作原理详解 (一)

    一.类加载器 首先来看一下java程序的执行过程. 从这个框图很容易大体上了解java程序工作原理.首先,你写好java代码,保存到硬盘当中.然后你在命令行中输入 javac YourClassNam ...

  3. Java虚拟机工作原理详解

    原文地址:http://blog.csdn.net/bingduanlbd/article/details/8363734 一.类加载器 首先来看一下java程序的执行过程. 从这个框图很容易大体上了 ...

  4. [转]java虚拟机工作原理详解

    一.类加载器 首先来看一下java程序的执行过程. 从这个框图很容易大体上了解java程序工作原理.首先,你写好java代码,保存到硬盘当中.然后你在命令行中输入 javac YourClassNam ...

  5. JAVA线程池原理详解一

    线程池的优点 1.线程是稀缺资源,使用线程池可以减少创建和销毁线程的次数,每个工作线程都可以重复使用. 2.可以根据系统的承受能力,调整线程池中工作线程的数量,防止因为消耗过多内存导致服务器崩溃. 线 ...

  6. Java中多线程原理详解

    Java是少数的集中支持多线程的语言之一,大多数的语言智能运行单独的一个程序块,无法同时运行不同的多个程序块,Java的多线程机制弥补了这个缺憾,它可以让不同的程序块一起运行,这样可以让程序运行更加顺 ...

  7. JAVA线程池原理详解(1)

    线程池的优点 1.线程是稀缺资源,使用线程池可以减少创建和销毁线程的次数,每个工作线程都可以重复使用. 2.可以根据系统的承受能力,调整线程池中工作线程的数量,防止因为消耗过多内存导致服务器崩溃. 线 ...

  8. Java并发--ReentrantLock原理详解

    ReentrantLock是什么? ReentrantLock重入锁,递归无阻塞的同步机制,实现了Lock接口: 能够对共享资源重复加锁,即当前线程获取该锁,再次获取不会被阻塞: 支持公平锁和非公平锁 ...

  9. Java虚拟机工作原理详解 ( 二 )

    首先这里澄清两个概念:JVM实例和JVM执行引擎实例,JVM实例对应了一个独立运行的Java程序,而JVM执行引擎实例则对应了属于用户运行程序的线程:也就是JVM实例是进程级别,而执行引擎是线程级别的 ...

随机推荐

  1. BufferedWriter字符缓冲输出流和BufferedReader字符缓冲输入流

    package com.yang.Test.BufferedStudy; import java.io.BufferedWriter; import java.io.FileWriter; impor ...

  2. Pref 社论

    目录 题面 题解 算法 1 算法 2 算法 3(标答) 代码 算法 1 20pts(by jijidawang) 40pts(by Rolling_Star) 算法 2 算法 3 题面 一个长度为 \ ...

  3. 清北学堂 2020 国庆J2考前综合强化 Day3

    目录 1. 题目 T1 石头剪刀布 题目描述 Sol T2 铺地毯 题目描述 Sol T3 数列游戏 题目描述 Sol T4 数星星 题目描述 Sol 2. 算法 -- 动态规划 1. 概述 2. 线 ...

  4. OPC UA分布式IO模块

    OPC UA IO模块对工业物联网的影响 OPC UA IO模块是指IO模块支持OPC UA协议,可以直接与OPC Client进行通信,这样就可以从OPC Client上直接远程通过以太网对IO口进 ...

  5. Java开发学习(二十二)----Spring事务属性、事务传播行为

    一.事务配置 上面这些属性都可以在@Transactional注解的参数上进行设置. readOnly:true只读事务,false读写事务,增删改要设为false,查询设为true. timeout ...

  6. Windows Embedded CE 6.0开发环境的搭建(2)

    最近开始在学习嵌入式,在这里首先得安装Windows Embedded CE 6.0,其中遇到了很多问题,电脑的系统以及相关配置都会在安装过程中受到影响,因此笔者就安装中的问题以及环境搭建来介绍一下. ...

  7. 设置Windows Server 2022、Win10、Win11自动登录的简单方法-OK

    这里介绍自己从使用 Windows Server 2003 到 Windows Server 2022 一直都在使用的自动登录系统的方法,屡试不爽.网上讨论的方法太繁琐,所以共享出来,供大家参考.该方 ...

  8. 如何构建 Apache DolphinScheduler 的 Docker 镜像

    继昨日发布第一个 [官方 Docker 镜像] 后,有几位小伙伴私信想自己进行编译,这里也将 Docker 的主要贡献者文禾同学整理的文档进行分享.以下是全文内容: 您能够在类 Unix 系统和 Wi ...

  9. 如何有效管理产品生命周期(How to Effectively Manage a Product Lifecycle)

    本文翻译自文章:How to Effectively Manage a Product Lifecycle 文章原文链接:https://medium.com/design-bootcamp/how- ...

  10. Redis 11 配置

    参考源 https://www.bilibili.com/video/BV1S54y1R7SB?spm_id_from=333.999.0.0 版本 本文章基于 Redis 6.2.6 基本配置 Re ...