JAVA分页处理的总结

数据分页

必须的的参数

总数据条数(count)
  • 来源:从数据库中查询获得
每页展示多少条数据(pageSize)
  • 来源:前端获取
当前所在的页码(currentPage)
  • 来源:前端获取
总页数(countPage)
  • 来源:计算得来

总页数 = 总数据条数 / 每页展示条数

countPage = count / pageSize

数据本身
  • 来源:数据库查询

物理分页

什么是物理分页

​ 所谓的物理分页其实就是直接通过数据库来实现返回一部分数据。每次只从数据库中查询一页的数据。与之相对应的还有逻辑分页。

Mysql中的实现语句
    SELECT * FROM `shop` LIMIT (currentPage-1)*pageSize, pageSize;
Java程序
private void doPhysicalPaganation(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
	
	// 获取页面传递过来的参数
	String sCurrentPage = req.getParameter("currentPage");
	String sPageSize= req.getParameter("pageSize");
	
	// 当前页码默认展示第一页
	int currentPage = 1;
	try {
		// 如果前端传递了具体的页码,我们就用前端传过来的
		currentPage = Integer.parseInt(sCurrentPage);
	} catch (NumberFormatException e) {
	}
	
	int pageSize = 10;
	try {
		// 如果前端传递了具体的页码,我们就用前端传过来的
		pageSize = Integer.parseInt(sPageSize);
	} catch (NumberFormatException e) {
	}
	
	Paganation<Student> paganation = new Paganation<>();
	paganation.setCurrentPage(currentPage);
	paganation.setPageSize(pageSize);
	
	// 分页查询
	studentDao.findByPageWithPhysical(paganation);
	
	req.setAttribute("page", paganation);
	
	req.getRequestDispatcher("physical.jsp").forward(req, resp);
}
public Paganation<Student> findByPageWithPhysical(Paganation<Student> pageParam) {
	
	Paganation<Student> page = pageParam;
	
	Connection conn = null;
	PreparedStatement pstmt = null;
	ResultSet rs = null;
	try {
		// 获取连接
		conn = JDBCTools.getConnection();
		
		// 获取当前页要展示的数据
		// 创建预编译对象,预编译SQL语句
		pstmt = conn.prepareStatement("select * from student limit ?,?");
		// limit关键字第一个参数表示跳过结果集中的多少条数据
		pstmt.setInt(1, (pageParam.getCurrentPage() - 1) * pageParam.getPageSize());
		// limit关键字第二个参数表示从结果集中取多少条数据
		pstmt.setInt(2, pageParam.getPageSize());
		
		// 执行语句,获取结果集
		rs = pstmt.executeQuery();
		
		// 封装结果集
		List<Student> datas = new ArrayList<Student>();
		while(rs.next()) {
			Student student = new Student();
			student.setStuId(rs.getString("stu_id"));
			student.setStuName(rs.getString("stu_name"));
			student.setSex(rs.getString("sex"));
			student.setAge(rs.getInt("age"));
			student.setScience(rs.getString("science"));
			student.setTelephone(rs.getString("telephone"));
			datas.add(student);
		}
		
		// 将获取到的当前页要展示的数据封装到page对象中
		page.setData(datas);
		
		// 查询总数据条数
		pstmt = conn.prepareStatement("select count(*) from student");
		rs = pstmt.executeQuery();
		int totalCount = 0;
		if(rs.next()) {
			totalCount = rs.getInt(1);
		}
		
		page.setTotalCount(totalCount);
		
	} catch (SQLException e) {
		e.printStackTrace();
	}
	
	return page;
}

逻辑分页

什么是逻辑分页

​ 所谓的逻辑分页其实就是通过内存来进行分页。具体来说,首次查询数据时,将所有数据都取出放到内存中,展示其他页的数据时,在内存中实现数据的截取,展示。

Mysql中的实现语句
  SELECT * FROM `shop` ;
Java程序
private void doLogicPaganation(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
	
	
	// 获取页面传递过来的参数
	String sCurrentPage = req.getParameter("currentPage");
	String sPageSize= req.getParameter("pageSize");
	
	// 当前页码默认展示第一页
	int currentPage = 1;
	try {
		// 如果前端传递了具体的页码,我们就用前端传过来的
		currentPage = Integer.parseInt(sCurrentPage);
	} catch (NumberFormatException e) {
	}
	
	int pageSize = 10;
	try {
		// 如果前端传递了具体的页码,我们就用前端传过来的
		pageSize = Integer.parseInt(sPageSize);
	} catch (NumberFormatException e) {
	}
	
	Paganation<Student> paganation = new Paganation<>();
	paganation.setCurrentPage(currentPage);
	paganation.setPageSize(pageSize);
	
	// 分页查询
	studentDao.findByPageWithLogic(paganation);
	
	req.setAttribute("page", paganation);
	
	req.getRequestDispatcher("logic.jsp").forward(req, resp);
	
	
}
List<Student> cache = new ArrayList<>();
public Paganation<Student> findByPageWithLogic(Paganation<Student> pageParam) {
	Paganation<Student> page = pageParam;
	
	Connection conn = null;
	PreparedStatement pstmt = null;
	ResultSet rs = null;
	try {
		List<Student> datas = null;
		// 当缓存中有数据时,直接从缓存中取当前页数据,无需查数据库
		if(cache.size() > 0) {
			datas = getPageData(page);
		} else {
			
			// 如果缓存中没有数据,从数据库中查询所有数据,放入缓存中
			
			// 获取连接
			conn = JDBCTools.getConnection();
			// 获取当前页要展示的数据
			// 创建预编译对象,预编译SQL语句
			pstmt = conn.prepareStatement("select * from student");
			
			// 执行语句,获取结果集
			rs = pstmt.executeQuery();
			
			// 封装结果集
			cache.clear();
			while(rs.next()) {
				Student student = new Student();
				student.setStuId(rs.getString("stu_id"));
				student.setStuName(rs.getString("stu_name"));
				student.setSex(rs.getString("sex"));
				student.setAge(rs.getInt("age"));
				student.setScience(rs.getString("science"));
				student.setTelephone(rs.getString("telephone"));
				cache.add(student);
			}
			
			// 将获取到的当前页要展示的数据封装到page对象中
			datas = getPageData(page);
		}
		
		page.setData(datas);
		page.setTotalCount(cache.size());
		
	} catch (SQLException e) {
		e.printStackTrace();
	}
	
	return page;
}

/**
 * 从缓存中获取当前页要展示的数据
 * @param page
 * @return
 */
private List<Student> getPageData(Paganation<Student> page) {
	List<Student> datas = new ArrayList<>();
	int startIdx = (page.getCurrentPage() - 1)*page.getPageSize();
	int endIdx = page.getCurrentPage() * page.getPageSize();
	if(endIdx > cache.size()) {
		endIdx = cache.size();
	}
	datas = cache.subList(startIdx, endIdx);
	return datas;
}

两种分页的优缺点

  1. 逻辑分页效率高,占用内存空间,适合查询的数据少但是查询次数多的情况。
  2. 物理分页效率低,节省内存空间,适合查询次数少但是查询数据较大的情况。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值