⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 abstractpage.java

📁 适合各种数据库的分页程序
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
package com.ztes.commons.dbo.pagination;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

import javax.sql.DataSource;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.dao.DataAccessResourceFailureException;
import org.springframework.jdbc.core.ColumnMapRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.SqlTypeValue;
import org.springframework.jdbc.core.StatementCreatorUtils;
import org.springframework.jdbc.datasource.DataSourceUtils;
import org.springframework.jdbc.support.JdbcUtils;
import org.springframework.util.Assert;

import com.ztes.commons.dbo.sql.SelectSqlParser;


/**
 * 分页的抽象类,提供分类的一些通用函数。不同的数据库分页建议继承该类实现。
 * 子类只需实现{@link #getPageSql(int, int)}方法。
 * 由于同时考虑到从存储过程中获取数据分页,可能逻辑有点混乱^_^。
 * 
 * @author tiannet(曾次清)
 */
public abstract class AbstractPage {

	/** sql语句分析器*/
	private SelectSqlParser sqlParser = null;
	
	/** 分页信息对象 */
	private PageInfo pageInfo = new PageInfo();
	
	/** JDBC操作模板 */
	private JdbcTemplate jdbcTemplate;
	
	/** 操作数据库的数据源 */
	private DataSource dataSource;
	
	/** 查询结果中每行的映射关系 */
	private RowMapper rowMapper;
	
	/** 查询sql语句 */
	private String querySql;
	
	/** 是否总是使用通用方法分页 */
	private boolean useCommonPage = false;
	
	/** 是否统计总记录数 */
	private boolean countRecord = true;
	
	/** 是否使用SQL语句分页,否则为存储过程 */
	private boolean pagedBySql = true;
	
	/** 存储过程名称 */
	private String procName;
	
	/** 存储过程输入参数值 */
	private Object[] procArgs;
	
	/** 日志管理 */
	protected Log logger = LogFactory.getLog( getClass() );
	
	//~ abstract methods ------------------------------------------------------------------
	
	/**
	 * 返回从指定位置开始获取指定记录的sql语句,如果无法通过sql获取获取记录,则返回null。
	 * @param start 获取记录的开始位置,从零开始计。
	 * @param size 获取记录的大小。
	 * @return 获取指定记录的sql语句。
	 */
	protected abstract String getPageSql(int start, int size);
	
	/**
	 * 获取指定记录中的某些记录。
	 * @param allData 所有记录集。
	 * @param start 记录开始位置,从0开始。
	 * @param size 获取记录大小。
	 * @return 截取从start开始,大小为size的记录。
	 */
	public List extractData(List allData, int start, int size) {
		Assert.notNull(allData,"allData not be null");
		pageInfo.setTotalCount( allData.size() );
		start = start < 0?0:start;
		int end = start + size;
		end = end > allData.size() ? allData.size():end; 
		return allData.subList(start, end);
	}
	
	/**
	 * 获取当前页数据,取决于当前页码、每页显示的记录数。
	 * @param allData 所有记录集。
	 * @return 当前页显示的数据。
	 */
	public List extractData(List allData) {
		Assert.notNull(allData,"allData not be null");
		pageInfo.setTotalCount( allData.size() );
		//查询所有记录
		if( pageInfo.isQueryAllElements() ) {
			return allData;
		}
		int start = pageInfo.getCurrentPageFirstElementNo();
		int size = pageInfo.getPageSize();
		return extractData(allData, start, size);
	}
	
	
	
	
	/**
	 * 获取从指定开始位置开始计的指定记录数。
	 * @param start 记录开始位置,从0开始。
	 * @param size 获取记录大小。
	 * @return List中的对象取决于RowMapper对象,如果未设置,则List的每个元素为一个Map对象,该Map以字段名称为key,
	 * 字段值为value。
	 */
	public List getData(int start, int size) {
		//----如果是从存储过程中获取数据
		if( !this.pagedBySql ) {
			return getDataFromProc( start, size, this.countRecord );
		}
		//----使用SQL分页
		//如果是SQl语句分页并且需统计总记录数
		if( getPageSql(start,size) != null && this.countRecord ) {
			pageInfo.setTotalCount(this.countRecordBySql());
		}
		return getDataExceptProc( start, size );
	}
	
	
	/**
	 * 获取当前页数据,取决于当前页码、每页显示的记录数。
	 * @return List中的对象取决于RowMapper对象,如果未设置,则List的每个元素为一个Map对象,该Map以字段名称为key,
	 * 字段值为value。
	 */
	public List getData() {
		//---- 如果是从存储过程中获取数据
		if( !this.pagedBySql ) {
			int size = pageInfo.isQueryAllElements() ? -1 : pageInfo.getCurrentPageSize();
			return getDataFromProc( pageInfo.getCurrentPageFirstElementNo(), size, this.countRecord );
		}
		//查询所有记录
		if( pageInfo.isQueryAllElements() ) {
			logger.debug("查询所有记录");
			List list = jdbcTemplate.query( getQuerySql(),  getRowMapper() );
			pageInfo.setTotalCount( list == null?0:list.size() );
			return list;
		}
		
		int start = pageInfo.getCurrentPageFirstElementNo();
		int size = pageInfo.getCurrentPageSize();
		
		//----使用SQL分页
		//如果是SQl语句分页并且需统计总记录数
		if( getPageSql(start,size) != null && this.countRecord ) {
			pageInfo.setTotalCount(this.countRecordBySql());
		}
		start = pageInfo.getCurrentPageFirstElementNo();
		size = pageInfo.getCurrentPageSize();
		return getDataExceptProc( start, size );
		
	}
	
	
	/**
	 * 设置持有分页参数的对象。
	 * 建议使用PageParameterMaker(request);得到实例,
	 * 该构造函数会自动获取当前页码、页尺寸、请求页面地址等参数。
	 * 对于普通的请求处理(尤其是翻页只在本页面跳转),建议使用该类初始化参数。
	 * @see com.ztes.commons.dbo.pagination.PageParameterMaker
	 * @see com.ztes.commons.dbo.pagination.PageParameterSimple
	 * @param pageParameter 持有分页参数的对象。
	 */
	public void initPageParameter(PageParameter pageParameter) {
		pageInfo.setPageParameter(pageParameter);
	}
	
	/**
	 * 设置分页配置信息。
	 * @param pageConfig 分页配置信息。
	 */
	public void setPageConfig(PageConfig pageConfig) {
		pageInfo.setPageConfig(pageConfig);
	}
	
	/**
	 * 设置操作数据库的数据源。
	 * @param dataSource 操作数据库的数据源。
	 */
	public void setDataSource(DataSource dataSource) {
		this.dataSource = dataSource;
		jdbcTemplate = new JdbcTemplate( dataSource );
	}
	
	/**
	 * 设置查询结果中每行的映射关系。
	 * @param rowMapper 查询结果中每行的映射关系。
	 */
	public void setRowMapper(RowMapper rowMapper) {
		this.rowMapper = rowMapper;
	}
	
	/**
	 * 设置是否使用通用的分页方法,即JDBC的接口分页。
	 * 默认情况下,程序会先判断能否支持sql语句分页,如果不支持则使用JDBC分页。
	 * 如果将该方法的参数设为true,则程序直接使用JDBC分页,对于SQLServer2000的分页,
	 * 可能存在很多不能使用SQL语句分页的情况({@link com.ztes.commons.dbo.pagination.impl.PageSqlServer}),
	 * 此时应将该方法的参数设为true,使用JDBC的相关方法从ResultSet中提取数据。
	 * @param useCommonPage 是否使用通用的方法分页,默认为否。
	 */
	public void setUseCommonPage(boolean useCommonPage) {
		this.useCommonPage = useCommonPage;
	}
	
	/**
	 * 设置是否统计总记录数,默认为统计。
	 * 对于数据量大的查询,为了避免因统计而影响效率,可以设置为不统计总记录数。
	 * @param countRecord 是否统计记录总数,默认为是。
	 */
	public void setCountRecord(boolean countRecord) {
		this.countRecord = countRecord;
	}
	
	/**
	 * 得到查询结果中每行的映射关系。如果用户未设置,则默认使用ColumnMapRowMapper。
	 * @return 查询结果中每行的映射关系。如果用户未设置,则默认使用ColumnMapRowMapper。
	 */
	public RowMapper getRowMapper() {
		if( this.rowMapper == null ) {
			this.rowMapper = new ColumnMapRowMapper();
		}
		return this.rowMapper;
	}
	
	/**
	 * 返回查询sql语句。
	 * @return 查询sql语句。
	 */
	public String getQuerySql() {
		if( querySql == null ) {
			throw new IllegalArgumentException("必须设置查询sql语句(querySql)");
		}
		return querySql;
	}

	/**
	 * 设置查询sql语句
	 * @param querySql 查询sql语句.
	 */
	public void setQuerySql(String querySql) {
		this.pagedBySql = true;
		this.querySql = querySql;
		sqlParser = new SelectSqlParser( querySql );
	}
	
	/**
	 * 设置从存储过程获取数据分页的一些参数。
	 * 它与{@link #setQuerySql(String)}只能同时使用其一。
	 * @param procName 存储过程名称。
	 * @param args 存储过程输入参数值,必须依照参数顺序。
	 */
	public void setProcSql(String procName, Object[] args) {
		//指明从存储过程中获取数据分页
		this.pagedBySql = false;
		this.procName = procName;
		this.procArgs = args;
	}
	
	/**
	 * 获取分页信息对象。
	 * @return 分页信息对象。
	 */
	public PageInfo getPageInfo() {
		return pageInfo;
	}
	
	/**
	 * 将翻页的链接统计等信息作为html代码返回。
	 * @return 翻页的链接统计等信息的html代码。
	 */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -