数据分页(物理分页和逻辑分页)

# 数据分页

## 必须的的参数

#### 总数据条数(count)

+ 来源:从数据库中查询获得

#### 每页展示多少条数据(pageSize)

+ 来源:前端获取

#### 当前所在的页码(currentPage)

+ 来源:前端获取

#### 总页数(countPage)

+ 来源:计算得来

> 总页数 = 总数据条数 / 每页展示条数
>
> countPage = count / pageSize

#### 数据本身

+ 来源:数据库查询

## 物理分页

#### 什么是物理分页

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

#### Mysql中的实现语句

```sql
SELECT * FROM `shop` LIMIT (currentPage-1)*pageSize, pageSize;
```

#### Java程序

```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);
}
```

```java
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中的实现语句

```sql
SELECT * FROM `shop` ;
```

#### Java程序

```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);

}
```

```java
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. 物理分页效率低,节省内存空间,适合查询次数少但是查询数据较大的情况。

原文地址:https://www.cnblogs.com/tsymqwb/p/11773787.html

时间: 2024-10-21 08:00:26

数据分页(物理分页和逻辑分页)的相关文章

ThinkPHP数据分页Page.class.php

获取分页类 ThinkPHP提供了数据分页的扩展类库Page,可以在http://www.thinkphp.cn/extend/241.html下载,或者下载官方的完整扩展包(http://www.thinkphp.cn/down/253.html)里面也已经包含分页扩展类了.把解压后的Page.class.php放入ThinkPHP/Extend/Library/ORG/Util/(如果没有请手动创建)目录下面. 当然,扩展类库的位置其实比较随意,你也可以放入项目的类库目录下面,区别只是在于你

【知了堂学习笔记】JSP页面数据分页实现(一)——分页概念以及主流数据库的分页查询

一.分页简介 1.分页,就是一种将数据库里的数据一部分展示给用户的技术.为什么要这样做呢?因为一般来说用户在查询时数据是非常多的,当一个页面不能显示所有数据时,我们就要对查询的数据进行分页,就像我们的书本分成一页一页一样.最简单的例子就是百度,当你百度时,成千上万的数据,并不是呈现在一个页面的. 2.分页的实现方式 1)假分页(不推荐):什么是假分页呢?假分页就是一次性将数据库里的数据全部取出来,存储在页面中,然后再将数据分别展示出来.这种假分页在数据少的还可以玩玩,当数据多起来的时候,这种方式

salesforce 零基础开发入门学习(八)数据分页简单制作

本篇介绍通过使用VF自带标签和Apex实现简单的数据翻页功能. 代码上来之前首先简单介绍一下本篇用到的主要知识: 1.ApexPages命名空间 此命名空间下的类用于VF的控制. 主要的类包括但不限于以下: ApexPages.StandardController:当为一个标准Controller定义扩展的时候使用此类.StandardController对象为Salesforce提供的预构建VF的控制器对象引用; ApexPages.Action:使用Action类和方法用于VF自定义控制器和

SqlSever大数据分页

在sql sever中大数据的分页一直是难以处理的一块,利用id自增列分页也存在不足之处.从一个相对全面的分页看,sql sever2005中新增的row_number()函数解决了这个问题.还是从一个实际项目开始介绍吧.中国铁建股份公司的项目表中数据很大,开发之初用的是GridView控件自带的分页,在运行一年以后,点击下一页终于是难以等待了,系统需要优化.对于分页的改进是业务的需要.于是,我采用了Row_number()函数分页.也算一解了燃眉之急. 说明:该篇文章只是一个案例的说明,更详细

大数据分页实现与性能优化

摘要:Web 应用程序中经常使用数据分页技术,该技术是提高海量数据访问性能的主要手段.实现web数据分页有多种方案,本文通过实际项目的测试,对多种数据分页方案深入分析和比较,找到了一种更优的数据分页方案Row_number()二分法.它依靠二分思想,将整个待查询记录分为2部分,使扫描的记录量减少一半,进而还通过对数据表及查询条件进行优化,实现了存储过程的优化.根据Row_number()函数的特性,该方案不依赖于主键或者数字字段,大大提高了它在实际项目中的应用,使大数据的分页效率得到了更显著的提

Sql Server 数据分页

1.引言 在列表查询时由于数据量非常多,一次性查出来会非常慢,就算一次查出来了,也不能一次性显示给客户端,所以要把数据进行分批查询出来,每页显示一定量的数据,这就是数据要分页. 2.常用的数据分页方法 我们经常会碰到要取n到m条记录,就是有分页思想,下面罗列一下一般的方法. 我本地的一张表 tbl_FlightsDetail,有300多W记录,主键 FlightsDetailID(Guid),要求按照FlightsDetailID排序 取 3000001 到3000010 之间的10条记录,也是

大数据分页解决方案

1 编写目的 解决系统需要检索大数据列表时的性能问题,而提出的分页方案 2 术语.定义和缩略语 3 大数据量检索的性能问题分析 大数据量检索的性能存在问题,问题主要包括 3.1 客户端在IE或者cs端数据量过大会导致IE变慢,甚至死锁 现象: IE浏览器崩溃 浏览器白板,停止响应 3.2 客户端--web服务器之间的数据传输量大会导致客户端速度变慢,效率降低 现象: IE浏览器长期在等待时白板 IE 浏览器操作慢 3.3 中间层构造大数据列表会导致中间层性能降低 现象: 并发访问多时,应用服务器

转Oracle、MySql、SQLServer 数据分页查询

最近简单的对oracle,mysql,sqlserver2005的数据分页查询作了研究,把各自的查询的语句贴出来供大家学习..... (一). mysql的分页查询 mysql的分页查询是最简单的,借助关键字limit即可实现查询,查询语句通式: /* * sql:可以是单表的查询语句,也可以是多表的联合查询语句 * firstIndex:其实的索引 * pageSize:每页显示的记录数 */ select o.* from (sql) o limit firstIndex,pageSize

一个高效的数据分页的存储过程 可以轻松应付百万数据

一个高效的数据分页的存储过程 可以轻松应付百万数据 CREATE PROCEDURE pageTest --用于翻页的测试--需要把排序字段放在第一列 (@FirstID nvarchar(20)=null, --当前页面里的第一条记录的排序字段的值@LastID nvarchar(20)=null, --当前页面里的最后一条记录的排序字段的值@isNext bit=null, --true 1 :下一页:false 0:上一页@allCount int output, --返回总记录数@pag