JAVA关于数据分页

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JAVA关于数据分页相关的知识,希望对你有一定的参考价值。

现在大多数分页是采用先统计总行数再读取分页数据,那么会执行了两条SQL语句。
我是搞JAVA WEB的,不同的请求就会有不同的线程来执行。

那么在程序里,假如我在调用了统计的SQL语句后,另一线程对数据表进行了修改(增加或删除行)恰好少了一页,此时本线程去读取分页数据就会失败。

有什么办法可以不通过程序的同步来解决这个并发问题?要事务???

参考技术A 给你提供两种思路: 1.你要取第二页,也就就是6-10,你可以先用top 10 ,取出前10个,然后desc倒序,再取出top 5 再倒序,这样就取出6-10个;比如:select top 5 from (select top 10 * from table_1 desc) t desc 2.sqlserver 和oracle都有row_number() 这样的列,就是你取出的结果集给你多加一个列,你按row_number()去结果集也行。 比如:with table001 as (select row_number() over (order by Qid) as row_number , * from ( "+sql+") k) select * from table001 where row_number>= ? and row_number<= ? order by Qid 这个是我之前项目中的sql语句。你参考一下,作用就是 取( "+sql+") 中的sql 中的两个?之间的数据 --------------------------- 你要取页数,可以用第二个思路,pk不一定是连续,可能有些数据给删除;但是查询出来的结果集加上的row_number(),肯定是连续, row_number%5==0;page = row_number/5 row_number%5!=0;page = row_number/5+1蓝屏追问

某些数据库不支持row_number,所以要从程序上解决。

参考技术B 对的 ,良好的习惯,就是对数据库增、删、改 操作都添加事务追问

我在说两次查询怎样确保原子

Java EE之分页器设计

由于数据库实训的课程设计,在做项目过程中,需要使项目更加规范的结构和各层间责任分离。无疑地,分页器是其中之一。

1. 本文仅陈述分页器如何实现,关于分页器的其他概念,请自行搜索其他网络资源。

2. 关于如何在各层使用使用PageBean,见本文引用文献3

一、设计实现

  

/**
 * 分页器
 * @author Zen Johnny
 * @date 2017年11月11日 下午1:19:32
 * @notice sql demo:SELECT * FROM table LIMIT 5,10;  // 检索记录行 6-15
 */
package com.cpms.entity.vo;

import java.util.Collections;
import java.util.List;

public class Pager<Entity> {
	
	/**
	 * 存放当前页的数据
	 */
	private List<Entity> entitys;
	
	/**
	 * 每页行数(记录数),默认为10
	 */
	private int pageSize;
	
	/**
	 * 默认的每页记录数为10(用于缺省构造器,无set方法)
	 */
	private static final int DEFAULT_PAGE_SIZE = 10;
	
	/**
	 * 总行数(总记录数)
	 */
	private int totalRows;
	
	/**
	 * 总页数 
	 */
	private int totalPage;
	
	/**
	 * 当前页数,默认为第一页
	 */
	private int curPage = 1;
	
	/**
	 * 前一页 
	 */
	private int prePage;
	
	/**
	 * 后一页
	 */
	private int nextPage;

	/**
	 * 数据库开始的指针
	 * limit begin,offset 中 的m
	 */
	private int beginCursor;
	
	/**
	 * 数据库查询记录时候的偏移量
	 * limit begin,offset 中 的 offset
	 */
	private int offsetCursor;
	
	/**
	 * constructor
	 */
	public Pager() {
		this(0, DEFAULT_PAGE_SIZE, 0, Collections.EMPTY_LIST);
	}

	/**
	 * constructor
	 */
	public Pager(int curPage, int pageSize, int totalRows,List<Entity> entitys) {
		this.entitys = entitys;
		//↓先得设置总记录和每个页面的记录数,才有办法知道【总页数】等属性
		this.totalRows = totalRows;
		setPageSize(pageSize);	
		
		//↓注意:1.条件:总记录数totalRows和每页记录数pageSize   2.此处计算非常容易产生精度损失
		setTotalPage();
		
		//↓条件:总页数totalPage
		setCurPage(curPage);
		
		//↓条件:当前页码curPage和每页记录数pageSize
		setBeginCursor();	
		//↓条件:每页记录数pageSize
		setOffsetCursor();	
		//↓条件:当前页页码curPage
		setPrePage();		
		//↓条件:当前页页码curPage和总页数totalPage
		setNextPage();
	}

	public List<Entity> getEntitys() {
		return entitys;
	}
	
	/**
	 * 设置当前页面数据对象,私有,对外屏蔽,防止破坏分页器各属性的一致性
	 */
	private void setEntitys(List<Entity> entitys) {
		this.entitys = entitys;
	}

	public int getPageSize() {
		return pageSize;
	}

	/** 
	 * 设置页面大小,私有,对外屏蔽,防止破坏分页器各属性的一致性
	 */
	private void setPageSize(int pageSize) {
		if(pageSize < 1) {
			pageSize = DEFAULT_PAGE_SIZE;
		}else {
			this.pageSize = pageSize;
		}
	}
	
	public static int getDefaultPageSize() {
		return DEFAULT_PAGE_SIZE;
	}

	public int getTotalRows() {
		return totalRows;
	}
	
	/** 
	 * 设置页总记录数,私有,对外屏蔽,防止破坏分页器各属性的一致性
	 */
	private void setTotalRows(int totalRows) {
		if(totalRows < 1)
			this.totalRows = 0;
		else
			this.totalRows = totalRows;
	}

	public int getTotalPage() {
		return totalPage;
	}
	
	/** 
	 * 设置总页面数,私有,对外屏蔽,防止破坏分页器各属性的一致性
	 */
	private void setTotalPage() {
		this.totalPage = (int) Math.ceil((double)totalRows/pageSize);
	}

	public int getCurPage() {
		return curPage;
	}

	public void setCurPage(int curPage) {
		if(curPage < 1)
			this.curPage = 1;
		else if(curPage > totalPage)
			this.curPage = totalPage;
		else
			this.curPage = curPage;
	}

	public int getPrePage() {
		return prePage;
	}

	private void setPrePage() {
		this.prePage = curPage - 1;
		if(this.prePage < 1) //注意:this.prePage[当前]
			this.prePage = 1;
	}

	public int getNextPage() {
		return nextPage;
	}
	
	/** 
	 * 设置下一页页码,私有,对外屏蔽,防止破坏分页器各属性的一致性
	 */
	private void setNextPage() {
		this.nextPage = curPage + 1;
		if(this.nextPage > totalPage)//注意:this.nextPage[当前]
			this.nextPage = totalPage;
	}

	public int getBeginCursor() {
		return beginCursor;
	}

	/**
	 *	设置数据库查询记录时的起始游标,私有,对外屏蔽,防止破坏分页器各属性的一致性
	 */
	private void setBeginCursor() {
		this.beginCursor = (curPage - 1) * pageSize;
	}

	public int getOffsetCursor() {
		return offsetCursor;
	}
	
	/**
	 *	设置数据库查询记录时的游标偏移量,私有,对外屏蔽,防止破坏分页器各属性的一致性
	 */
	private void setOffsetCursor() {
		this.offsetCursor = pageSize;
	}
	
	/**
	 * 是否还有上一页
	 */
	public boolean hasPrePage() {
		if(this.prePage == 1) {
			return false;
		}
			return true;
	}
	
	/**
	 * 是否还有下一页
	 */
	public boolean hasNextPage() {
		if(this.nextPage == this.totalPage) {
			return false;
		}
			return true;
	}
	
	@Override
	public String toString() {
		return "Pager [entitys=" + entitys + ", pageSize=" + pageSize + ", totalRows=" + totalRows + ", totalPage="
				+ totalPage + ", curPage=" + curPage + ", prePage=" + prePage + ", nextPage=" + nextPage
				+ ", beginCursor=" + beginCursor + ", offsetCursor=" + offsetCursor + "]";
	}
	
}

 

 

二、参考文献

  1.[强大的 java 分页器]http://blog.csdn.net/hcmdy/article/details/25251911

  2.[java--分页查询接口设计及分页器的实现]http://blog.csdn.net/u011659172/article/details/18231509

  3.[Java Web(十一) 分页功能的实现]https://www.cnblogs.com/whgk/p/6474396.html

以上是关于JAVA关于数据分页的主要内容,如果未能解决你的问题,请参考以下文章

关于分页,如果每页10个数据,n个数据有多少页?如果每页x个数据呢?用c#解答,很急

Java EE之分页器设计

关于分页

关于数据分页

关于数据分页

关于easyUI分页