扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
O(∩_∩)O~
创新互联建站主营陆丰网站建设的网络公司,主营网站建设方案,成都App定制开发,陆丰h5微信小程序开发搭建,陆丰网站营销推广欢迎陆丰等地区企业咨询
真巧,我最近也在研究分页技术,当时我用的是STRUTS+JDBC+JSP做的网上类当当网,
我总结的,你看看。
下面经过我测试,肯定正确。
你自己再理理。
目前比较广泛使用的分页方式是将查询结果缓存在HttpSession或有状态bean中,翻页的时候从缓存中取出一页数据显示。这种方法有两个主要的缺点:一是用户可能看到的是过期数据;二是如果数据量非常大时第一次查询遍历结果集会耗费很长时间,并且缓存的数据也会占用大量内存,效率明显下降。
其它常见的方法还有每次翻页都查询一次数据库,从ResultSet中只取出一页数据(使用rs.last();rs.getRow()获得总计录条数,使用rs.absolute()定位到本页起始记录)。这种方式在某些数据库(如oracle)的JDBC实现中差不多也是需要遍历所有记录,实验证明在记录数很大时速度非常慢。
至于缓存结果集ResultSet的方法则完全是一种错误的做法。因为ResultSet在Statement或Connection关闭时也会被关闭,如果要使ResultSet有效势必长时间占用数据库连接。
因此比较好的分页做法应该是每次翻页的时候只从数据库里检索页面大小的块区的数据。这样虽然每次翻页都需要查询数据库,但查询出的记录数很少,网络传输数据量不大,如果使用连接池更可以略过最耗时的建立数据库连接过程。而在数据库端有各种成熟的优化技术用于提高查询速度,比在应用服务器层做缓存有效多了。
在oracle数据库中查询结果的行号使用伪列ROWNUM表示(从1开始)。例如select * from employee where rownum10 返回前10条记录。但因为rownum是在查询之后排序之前赋值的,所以查询employee按birthday排序的第100到120条记录应该这么写:
select * from ( select my_table.*, rownum as my_rownum from ( select name, birthday from employee order by birthday ) my_table where rownum 120 ) where my_rownum=100
mySQL可以使用LIMIT子句:
select name, birthday from employee order by birthday LIMIT 99,20
DB2有rownumber()函数用于获取当前行数。
SQL Server没研究过,
在WEB的项目中,总免不了要分页,在以前的项目中一般都是采用SQL语言去分页,但SQL语言不好的一个
地方就是每种数据库可能有一些不同,用hibernate是可以解决这个问题,但是我们的项目没有用到任何
框架,主要的技术是jsp+javaBean+servlet,是表现层我采用的是面向对象的方法,数据库中的每个表对
应一个javaBean,表中的每条记录就是一个javaBean的对象,所以分页程序我也采用面向对象,只要在前
台拿到一个表的所有记录,用一个list存起来,然后用进list进行分页即可.
具体的分页程序如下:
1 import java.util.*;
2
3 /**
4 * 些类负责分页显示
5 * @author feng
6 */
7 public class PaginationE
8 {
9 private int pageSize;;//每页记录数
10 private int pageCount;//总页数
11
12
13 public ListE getList(ListE list,int pageCur){
14 ListE pageList = new ArrayListE();
15 int count = 0;
16 count = list.size();
17 if( count pageCur*pageSize){
18 for(int i = (pageCur-1)*pageSize;i count;i++){
19 pageList.add(list.get(i));
20 }
21 }else{
22 for(int i = (pageCur-1)*pageSize;i pageCur*pageSize;i++){
23 pageList.add(list.get(i));
24 }
25 }
26 return pageList;
27 }
28
29 public int getPageCount(ListE list){
30 int sum = 0;
31 sum = list.size();
32 pageCount = sum/pageSize + 1;
33 return pageCount;
34 }
35
36 public int getPageSize(){
37 return this.pageSize;
38 }
39 public void setPageSize(int pageSize){
40 this.pageSize = pageSize;
41 }
42 }
43
在前台只要把数据库的数据取出,将他放进List中,然后进行分页即可,例如:
有一表user,对应有javaBean为User,先声明一个List
ListUser list =new ListUser();
然后将user表中的所有记录查出,然后add进list中,
下面是分页
PaginationUser p = new PaginationUser();
p.setPageSize(10);
pageCount = p.getPageCount(list);
list = p.getList(list,1)
返回的list就是一页的对象了,按顺序取出显示即可.
如果数据库里有1000万条记录,你就把1000万条全取出来?
1.这样每次都取全部记录,对数据库的压力非常大,性能非常差
2.全部记录都取出来,放在List中,会造成内存溢出
rowid: 表示了记录的物理地址(不一定是连续的) 是唯一存在的
rownum:表示了记录的行号(是连续的)
两者没有必然的联系,所以rowid排在前面的行,rownum不一定排在前面。
oracle数据库中,已建立好的存储过程信息存储在系统表ALL_SOURCE 中,需要用sysdba身份登录数据库,进行查询操作,SQL命令如下:
1
2
3
4
5
SELECT line,text FROM ALL_SOURCE
WHERE TYPE='PROCEDURE'
AND NAME='过程名称'
AND OWNER='用户名'
ORDER BY line;
存储过程分成多行,每一行会存储为一条数据,所以,查询出来的会是多行,line表示行号。
ALL_SOURCE 表中还存储了以下类型信息:
1
2
3
4
5
6
7
8
9
10
SQL select distinct type from all_source ;
TYPE
------------
TYPE (对象)类型
TYPE BODY 类型体
PROCEDURE a href=";tn=44039180_cprfenlei=mv6quAkxTZn0IZRqIHckPjm4nH00T1dWrjmvuWfvrycYrAmzuH7B0ZwV5Hcvrjm3rH6sPfKWUMw85HfYnjn4nH6sgvPsT6KdThsqpZwYTjCEQLGCpyw9Uz4Bmy-bIi4WUvYETgN-TLwGUv3EnW6srHTsrjnz" target="_blank" class="baidu-highlight"存储过程/a
FUNCTION 函数
TRIGGER a href=";tn=44039180_cprfenlei=mv6quAkxTZn0IZRqIHckPjm4nH00T1dWrjmvuWfvrycYrAmzuH7B0ZwV5Hcvrjm3rH6sPfKWUMw85HfYnjn4nH6sgvPsT6KdThsqpZwYTjCEQLGCpyw9Uz4Bmy-bIi4WUvYETgN-TLwGUv3EnW6srHTsrjnz" target="_blank" class="baidu-highlight"触发器/a
PACKAGE 包
PACKAGE BODY 包体
通过:rowid。
sql如下:
select t.*,t.rowid from tablename t where ......;
解释:rowid就是oracle默认的行号,不管你的记录设怎么样的形式,第一列行号永远是1,以此类推。
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流