java oracle 分页怎么分页?

举例详解用Java实现web分页功能的方法
作者:treeroot
字体:[ ] 类型:转载 时间:
这篇文章主要介绍了举例详解用Java实现web分页功能的方法,这种基本功能现一般通过Hibernate框架来完成,需要的朋友可以参考下
分页问题是一个非常普遍的问题,开发者几乎都会遇到,这里不讨论具体如何分页,说明一下Web方式下分页的原理。首先是查询获得一个结果集(表现为查询数据库获得的结果),如果结果比较多我们一般都不会一下显示所有的数据,那么就会用分页的方式来显示某些数据(比如20条)。因为Http的无状态性,每一次提交都是当作一个新的请求来处理,即使是换页,上一次的结果对下一次是没有影响的。
这里总结三种实现分页的方式,不知道还有没有别的!
1.每次取查询结果的所有数据,然后根据页码显示指定的纪录。
2.根据页面只取一页数据,然后显示这一页,这里要构造sql语句。
3.取一定页数的数据,就是前面两种的折中。
这里还要注意的是这些数据是放在request还是session中,这里一一讨论
1.一般不会放在session中,因为会占用大量内存,所以要放在request里面。
优点:实现比较简单,查询速度比较快。
缺点:占用内存多一些,网络传输数据多。
对于数据量比较少的查询这种方法比较合适。这里有人把数据放在session中,这样换页的时候就不用重新查询,但是这样是极其不好的,强烈建议不要这样使用。
2.肯定不会放在session中,因为放在session中没有意义。
优点:占用内存少。
缺点:比较麻烦,必须先获得查询结果的总数,因为要知道有多少纪录才知道有多少页。另外要构造分页查询语句,对于不同的数据库是不一样的。
3.这种情况是肯定放在session中了,要不然我干吗取好几页呀,这样的实现是为了减少数据库查询的次数,比如我保存第1到10的纪录,那么换页的时候如果在1到10之间就可以直接从session获取。如果换到11页,我可以重新设置缓存11到
20页的数据(或者5到15页的数据),这样的话换10次才需要一次数据库查询操作。
优点:占用内存相对不多,提高平均查询速度。
缺点:实现起来更加复杂,可能存在脏数据,需要自己定义一个缓存集合。如果查询的数据量比较大,可以考虑采用这样方式。
下面的设计每次只获取一页数据,每次都要重新设置查询总数,具体如何获得自己实现,这是一个比较通用的分页实现。
这里设计一个接口:
package treeroot.
import java.util.L
* 该接口用来实现分页功能,注意这里没有提供修改的功能。
* @author treerot
* @version 1.0
public interface Pageable
  * 获得数据结果
  * @return
  public List getResult();
  * 获得查询总数
  * @return
  public int getCount();
  * 获得每页纪录数
  * @return
  public int getPageSize();
  * 获得当前页编号
  * @return
  public int getCurrentPage();
  * 获得总页数
  * @return
  public int getPages();
  * 每页默认显示纪录数
  public final static int DEFAULT_PAGESIZE=20;
这个接口非常简单,就是包括一个结果列表和一些分页的必要信息,这里注意几点:
1.这个接口的实现表示的是某一次查询的某一页数据,和上次查询无关
2.这个接口的实现应该是只读的,也就是说不可以修改的。
3.getPages()方法是冗余的,但是这里仍然提供这个方法。
下面给出一个抽象实现:
package treeroot.
import java.util.L
* @author treerot
* @version 1.0
public abstract class AbstractPage implements Pageable
  private int currentP
  private int pageS
  protected L
  * 指定当前页 
  * @param currentPage
  * @throws PageException
  public AbstractPage(int currentPage){
    this(currentPage,Pageable.DEFAULT_PAGESIZE);
  * 指定当前页和页大小
  * @param currentPage
  * @param pageSize
  * @throws PageException
  public AbstractPage(int currentPage,int pageSize) {
    this.currentPage=currentP
    this.pageSize=pageS
  protected void checkPage(int currentPage) throws PageException{
    if((currentPage&1)||(currentPage&this.getPages()))
       throw new PageException("页超出范围:总页数为"+this.getPages()+",当前页为"+currentPage);
  * 这个方法被子类重写用来初始化,也就是计算count值和result结果,在子类 的构造函数中调用。
  abstract protected void init() throws PageE
  public List getResult()
  public int getCount()
  public int getPageSize()
    return pageS
  public int getCurrentPage()
    return currentP 
  public int getPages()
    if(pages==0) this.pages=(count+pageSize-1)/pageS
这个抽象类实现了接口中的所有方法,但是定义了一个抽象方法init(),在子类中必须实现这个方法。上面的一个接口和一个抽象类看起来比较简单,你可能会觉得好像什么都没有做,实现上确实没有做什么,但是却可以给开发带来很大的帮助。我们可以根据自己的需要要继承这个抽象类,而数据可以通过各种方式获得,比如直接通过一个List获得,或者通过JDBC,Hibernate等等,不过我们都需要把结果封装到一个List里面,通过Hibernate就显得特别方便了。
PageException是自定义的一个异常
package treeroot.util   
* @author treeroot
* @version 1.0
public class PageException extends Exception
  public PageException(){
    super();
  public PageException(String message){
    super(message);
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具10338人阅读
java(23)
oracle(1)
& & & &&分页是系统中常用到的功能,只要涉及到查询必定伴随而来的就是分页,之前也学习过关于分页的内容,例如在牛腩的新闻发布系统,之前学习的大部分都是使用了假分页,这次学习java,使用Oracle数据库来实现一下真分页。
&&&&&&首先来说一下实现这个分页查询的流程:
一、封装分页信息:
&&&&&&&&需要分页的部分我们首先要做的是为分页封装一个分页实体,方便返回查询信息,封装如下:
*封装分页信息
* @author YoungJong
public class PageModel&E& {
private List&E&
//查询记录数
private int totalR
//每页多少条记录
private int pageS
private int pageNo;
public List&E& getList() {
public void setList(List&E& list) {
this.list =
public int getTotalRecords() {
return totalR
public void setTotalRecords(int totalRecords) {
this.totalRecords = totalR
public int getPageSize() {
return pageS
public void setPageSize(int pageSize) {
this.pageSize = pageS
public int getPageNo() {
return pageNo;
public void setPageNo(int pageNo) {
this.pageNo = pageNo;
public int getTotalPages(){
return(totalRecords+pageSize-1)/pageS
* 取得首页
public int getTopPageNo(){
public int getPreviousPageNo(){
if(pageNo&=1){
return pageNo-1;
public int getNextPageNo() {
if (pageNo &= getBottomPageNo()) {
return getBottomPageNo();
return pageNo + 1;
* 取得尾页
public int getBottomPageNo(){
return getTotalPages();
& & &&这里的重点是这个实体使用了泛型,使用分页显示的数据并不全是同一种实体数据,为了更好的复用分页查询,将结果集定义成泛型,则便于众多信息的查询:
二、页面加载显示查询数据并分页显示(Servlet):
&&&&&&&&页面加载时调用一个Servlet,通过Servelt来调用分页查询并将查询结果返回到页面:我们先来看Servlet的代码实现:
public class SearchItemServlet extends AbstractItemServlet {
* 覆盖servlet的doGet方法
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// 定义显示第几页的变量
int pageNo=0;
//int pageSize=2;
//从配置文件读取每页设置的显示数据数量
int pageSize=Integer.parseInt(this.getServletContext().getInitParameter(&page-size&));
//获取jsp传递过来的显示第几页
String pageNoString=req.getParameter(&pageNo&);
//如果为空则显示第一页
if(pageNoString==null){
pageNo=Integer.parseInt(pageNoString);
//取得查询条件条件,条件为空则查询全部
String condation=req.getParameter(&clientIdOrName&);
//调用分页查询方法,返回查询数据
PageModel pageModel=itemManager.findItemList(pageNo, pageSize, condation);
///取得查询页面传递过来的分页实体
req.setAttribute(&pageModel&, pageModel);
//将查询数据在页面显示
req.getRequestDispatcher(&/basedata/item_maint.jsp&).forward(req, resp);
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// TODO Auto-generated method stub
//super.doPost(req, resp);
doGet(req,resp);
其中值得注意的是,关于每页显示数据条数的问题,这一部分可以自己写在代码里,也可以将显示的数目写在配置文件中,只需要读取配置文件即可,方便配置:
其中配置文件可以这样写:在WEB-INF下的web.xml中:
&context-param&
&param-name&page-size&/param-name&
&param-value&3&/param-value&
&/context-param&
这种写法是可以适用于系统中所有的Servlet的,每一个想读取页面显示数量的都可以进行读取。
三、Dao层实现分页查询:
&&&&&& Servlet调用查询方法是通过一个Manager的接口,类似于三层中B层的作用,由于没有复杂的逻辑,所以这里的代码很简单:
* 查询物料信息,参数分别为:页码,每页显示数据,查询条件
public PageModel findItemList(int pageNo, int pageSize, String condation) {
Connection conn=
conn=DbUtil.getConnection();
//调用Dao层的分页查询
return itemDao.findItemList(conn, pageNo, pageSize, condation);
DbUtil.close(conn);
真分页查询的重点在于DAO层的实现,下面我们来看一下代码:
* 分页查询
public PageModel findItemList(Connection conn,int pageNo, int pageSize, String condation) {
StringBuffer sbSql=new StringBuffer();
sbSql.append(&select * &)
.append(&from (&)
.append(&select i.*, rownum rn from (&)
.append(&select a.item_no, a.item_name, a.spec, a.pattern, a.item_category_id, &)
.append(&b.name as item_category_name, a.item_unit_id, c.name as item_unit_name, a.file_name &)
.append(&from t_items a, t_data_dict b, t_data_dict c &)
.append(&where a.item_category_id=b.id and a.item_unit_id=c.id
if (condation != null && !&&.equals(condation)) {
sbSql.append(& and (a.item_no like '& + condation + &%' or a.item_name like '& + condation + &%') &);
sbSql.append(& order by a.item_no&)
.append(&) i where rownum&=? &)
.append(&) &)
.append(&where rn &? &);
System.out.println(&sql=& + sbSql.toString());
//通常采用日志组件记录,如log4j, 级别:info,debug,error...
PreparedStatement pstmt =
ResultSet rs =
PageModel pageModel =
//为查询条件参数赋值
pstmt = conn.prepareStatement(sbSql.toString());
//查询数据库中列在如何条件之间的数据
pstmt.setInt(1, pageNo * pageSize);
pstmt.setInt(2, (pageNo - 1) * pageSize);
int i=pageNo*pageS
int j=(pageNo - 1) * pageS
rs = pstmt.executeQuery();
//获得符合条件的信息结婚
List itemList = new ArrayList();
while (rs.next()) {
Item item = new Item();
item.setItemNo(rs.getString(&item_no&));
item.setItemName(rs.getString(&item_name&));
item.setSpec(rs.getString(&spec&));
item.setPattern(rs.getString(&pattern&));
//构造ItemCategory
ItemCategory ic = new ItemCategory();
ic.setId(rs.getString(&item_category_id&));
ic.setName(rs.getString(&item_category_name&));
item.setItemCategory(ic);
//构造ItemUnit
ItemUnit iu = new ItemUnit();
iu.setId(rs.getString(&item_unit_id&));
iu.setName(rs.getString(&item_unit_name&));
item.setItemUnit(iu);
item.setFileName(rs.getString(&file_name&));
itemList.add(item);
//为分页实体赋值
pageModel = new PageModel();
pageModel.setPageNo(pageNo);
pageModel.setPageSize(pageSize);
pageModel.setList(itemList);
//根据条件取得记录数
int totalRecords = getTotalRecords(conn, condation);
pageModel.setTotalRecords(totalRecords);
}catch(SQLException e) {
e.printStackTrace();
//记录到日志文件 error
throw new ApplicationException(&分页查询失败&);
}finally {
DbUtil.close(rs);
DbUtil.close(pstmt);
return pageM
其实看起来复杂,做起来逻辑并不复杂,很容易实现
四、jsp页面显示
& & 后台获得了数据,传递到页面,页面接收后就可以在页面上进行显示了,其实获得数据的代码一句话就可以搞定:更Servlet的代码是对应的,因为在Servlet中我们已经使用了setAttribute,所以jsp中的代码如下:
PageModel pageModel= (PageModel) request.getAttribute(&pageModel&);
& &点击跳到首页的方法如下(其他跳转类似不一一列出):
//跳转到首页
function topPage() {
window.self.location=&&%=basePath%&servlet/item/SearchItemServlet?pageNo=&%=pageModel.getTopPageNo()%&&clientIdOrName=&%=clientIdOrName%&&;
& & &这是一个完整的分页查询的流程,很多都是封装好的可以复用,只是在DAO层的查询语句需要自己写,不过最近了解了一些NHiernate,关于Hibernate的知识也在学习中,自己要写sql语句的问题也是可以解决的!
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:201936次
积分:7250
积分:7250
排名:第2263名
原创:139篇
评论:1616条
阅读:20013
(2)(4)(4)(4)(4)(4)(4)(3)(4)(4)(3)(4)(3)(2)(4)(2)(4)(4)(4)(3)(4)(4)(3)(4)(4)(3)(4)(4)(4)(4)(4)(4)(4)(4)(3)(6)(6)(1)<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
您的访问请求被拒绝 403 Forbidden - ITeye技术社区
您的访问请求被拒绝
亲爱的会员,您的IP地址所在网段被ITeye拒绝服务,这可能是以下两种情况导致:
一、您所在的网段内有网络爬虫大量抓取ITeye网页,为保证其他人流畅的访问ITeye,该网段被ITeye拒绝
二、您通过某个代理服务器访问ITeye网站,该代理服务器被网络爬虫利用,大量抓取ITeye网页
请您点击按钮解除封锁&<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
您的访问请求被拒绝 403 Forbidden - ITeye技术社区
您的访问请求被拒绝
亲爱的会员,您的IP地址所在网段被ITeye拒绝服务,这可能是以下两种情况导致:
一、您所在的网段内有网络爬虫大量抓取ITeye网页,为保证其他人流畅的访问ITeye,该网段被ITeye拒绝
二、您通过某个代理服务器访问ITeye网站,该代理服务器被网络爬虫利用,大量抓取ITeye网页
请您点击按钮解除封锁&

我要回帖

更多关于 java oracle 分页 的文章

 

随机推荐