📄 abstractpage.java
字号:
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 + -