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

📄 abstractpage.java

📁 适合各种数据库的分页程序
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
	public String getPageHtml() {
		return pageInfo.toHtml();
	}
	
	
	/**
	 * 返回sql语句分析器。
	 * @return sql语句分析器
	 */
	public SelectSqlParser getSqlParser() {
		if( sqlParser == null ) {
			throw new IllegalArgumentException("必须设置查询sql语句(querySql)");
		}
		return sqlParser;
	}
	//~ private methods----------------------------------------------------------------------------------
	
	/**
	 * 仅获取从指定开始位置开始计的指定记录数(不包括对存储过程的操作),不统计记录总数。
	 * @param start 记录开始位置,从0开始。
	 * @param size 获取记录大小。
	 * @return List中的对象取决于RowMapper对象,如果未设置,则List的每个元素为一个Map对象,该Map以字段名称为key,
	 * 字段值为value。
	 */
	private List getDataExceptProc(int start, int size) {
		//----使用SQL分页
		//如果指定了使用通用方法分页
		if( useCommonPage ) {
			return getDataUseJdbc( start, size );
		}
		String sql = getPageSql( start, size );
		if( sql != null ) {
			//String sql = getPageSql( start, size );
			logger.debug("使用sql语句获取指定数据(" + sql + ")");
			return jdbcTemplate.query(sql,  getRowMapper() );
		} else {
			return getDataUseJdbc( start, size );
		}
	}//~ getDataExceptProc
	
	/**
	 * 直接利用JDBC获取指定记录。
	 * @param start 开始记录,从零开始计。
	 * @param size 获取记录大小。
	 * @throws SQLException 
	 */
	@SuppressWarnings("unchecked")
	private List getDataUseJdbc(int start, int size) {
		logger.debug("从整个ResultSet中截取指定数据");
		List list = new ArrayList();
		Statement stmt = null;
		ResultSet rs = null;
		Connection conn = null;
		if( start < 0 ) {
			start = 0;
		}
		try {
			conn = DataSourceUtils.getConnection( getDataSource() );
			if( pageInfo.getPageConfig().isSupportScrollableResultSet() ) {
				if( logger.isDebugEnabled() ) {
					logger.debug("使用可滚动的结果集获取数据");
				}
				//如果支持滚动
				stmt = conn.createStatement(
						ResultSet.TYPE_SCROLL_INSENSITIVE,
						ResultSet.CONCUR_READ_ONLY);
				rs = stmt.executeQuery( getQuerySql() );
				//如果统计总记录数
				if( this.countRecord ) {
					rs.last();
					//得到记录总数
					pageInfo.setTotalCount(rs.getRow());
					if(  start > pageInfo.getTotalCount() ) {
						start = 0;
					}
				}
				if( start <= 0 ) {
					rs.beforeFirst();
				} else {
					rs.absolute( start );
				}
				int last = start + size;
				while( rs.next() && ++start <= last ) {
					list.add( this.getRowMapper().mapRow(rs, 0) );
				}
			} else {
				if( logger.isDebugEnabled() ) {
					logger.debug("JDBC不支持滚动的结果集,通过循环定位结果集");
				}
				int count = 0;
				//不支持滚动,逐行滚动到指定位置
				stmt = conn.createStatement();
				rs = stmt.executeQuery( getQuerySql() );
				for( int i = 0;i < start;i ++ ) {
					rs.next();
					count ++;
				}
				int last = start + size;
				while( ++start <= last && rs.next()  ) {
					list.add( this.getRowMapper().mapRow(rs, 0) );
					count ++;
				}
				//如果统计总记录数
				if( this.countRecord ) {
					while( rs.next() ) {
						count ++;
					}
					//设置总记录数
					pageInfo.setTotalCount( count );
				}//end if
			}//end 是否支持滚动结果集的判断
			
		} catch( SQLException sqlex ) {
			logger.error(sqlex.getMessage());
			throw new DataAccessResourceFailureException( sqlex.getMessage() );
			
		} finally {
			JdbcUtils.closeResultSet(rs);
			JdbcUtils.closeStatement(stmt);
			DataSourceUtils.releaseConnection(conn, getDataSource());
		}
		return list;
	}//~ getDataUseJdbc
	
	/**
	 * 从存储过程中获取数据,适合只有输入参数的存储过程。
	 * 如果欲获取所有记录,请将size大小设为小于0的数。
	 * @param start 开始记录,从零开始计。
	 * @param size 获取记录大小。
	 * @param isTotal 是否统计所有记录。
	 * @throws SQLException 
	 */
	@SuppressWarnings("unchecked")
	private List getDataFromProc( int start, int size, boolean isTotal) {
		List list = new ArrayList();
		CallableStatement stmt = null;
		ResultSet rs = null;
		Connection conn = null;
		try {
			//总记录数
			int total = 0;
			//构造执行存储过程的sql语句
			String sql = "{call " + procName + "(";
			if( procArgs != null && procArgs.length > 0 ) {
				sql += "?";
				for( int i = 1;i < procArgs.length;i ++ ) {
					sql += ",?";
				}
			}
			sql += ")}";
			conn = DataSourceUtils.getConnection( getDataSource() );
			if( pageInfo.getPageConfig().isSupportScrollableResultSet() ) {
				if( logger.isDebugEnabled() ) {
					logger.debug("使用可滚动的结果集获取数据(查询存储过程" + sql + ")");
				}
				//如果支持滚动
				stmt = conn.prepareCall(sql,
						ResultSet.TYPE_SCROLL_INSENSITIVE,
						ResultSet.CONCUR_READ_ONLY);
				//设置参数值
				setStatementValues( stmt, procArgs );
				rs = stmt.executeQuery();
				//如果并非获取所有数据,则定位至相应的游标号
				if( size >= 0 ) {
					//如果需求得总记录数
					if( isTotal  ) {
						rs.last();
						total = rs.getRow();
						//System.out.println("total=" + total);
					}
					//经测试,com.sybase.jdbc2.jdbc.SybDriver驱动不能使用absolute(0);
					if( start <= 0 ) {
						rs.beforeFirst();
					} else {
						rs.absolute( start );
					}
				}
			} else {
				if( logger.isDebugEnabled() ) {
					logger.debug("JDBC不支持滚动的结果集,通过循环定位结果集(查询存储过程" + sql + ")");
				}
				//不支持滚动,逐行滚动到指定位置
				stmt = conn.prepareCall(sql);
				//设置参数值
				setStatementValues( stmt, procArgs );
				rs = stmt.executeQuery();
				//如果并非获取所有数据,则定位至相应的游标号
				if( size >= 0 ) {
					if( logger.isDebugEnabled() ) {
						logger.debug("循环滚动至第" + start + "条记录");
					}
					for( int i = 0;i < start;i ++ ) {
						++total;
						rs.next();
					}
				}

			}//~ 是否支持滚动的结果集判断
			
			if( size >= 0 ) {
				//如果并非获取所有数据
				int last = start + size;
				int trueSize = 0; 
				if( logger.isDebugEnabled() ) {
					logger.debug("获取" + start + "至" + last + "记录");
				}
				while( ++start <= last && rs.next()  ) {
					trueSize ++;
					list.add( this.getRowMapper().mapRow(rs, 0) );
				}
				//继续移动游标,取得总记录数
				if( isTotal ) {
					if( !pageInfo.getPageConfig().isSupportScrollableResultSet() ) {
						//如果不支持滚动的结果集,总记录需追加已被取记录
						total += trueSize;
						//循环结束才能取得总记录数
						while(  rs.next() ) {
							++total;
						}
					}
					pageInfo.setTotalCount(total);
				}
			} else {
				//如果获取所有数据
				total = 0;
				while( rs.next() ) {
					++ total;
					list.add( this.getRowMapper().mapRow(rs, 0) );
				}
				pageInfo.setTotalCount(total);
			}
			
		} catch( SQLException sqlex ) {
			logger.error(sqlex.getMessage());
			throw new DataAccessResourceFailureException( sqlex.getMessage() );
			
		} finally {
			JdbcUtils.closeResultSet(rs);
			JdbcUtils.closeStatement(stmt);
			DataSourceUtils.releaseConnection(conn, getDataSource());
		}
		return list;
	}//~ getDataFromProc
	
	/**
	 * 获取操作数据库的数据源。
	 * @return
	 */
	private DataSource getDataSource() {
		if( dataSource == null ) {
			throw new IllegalArgumentException("必须设置DataSource");
		}
		return this.dataSource;
	}
	
	/**
	 * 根据SQL语句统计总记录数。
	 *
	 */
	private int countRecordBySql() {
		long time1 = System.currentTimeMillis();
		int totalCount = jdbcTemplate.queryForInt( sqlParser.getCountSql() );
		long time2 = System.currentTimeMillis();
		//如果统计记录所耗时间大于2秒,则写入警告日志
		if( time2 - time1 > 2000 ) {
			logger.warn("统计查询记录总数消耗时间" + (time2 - time1) + "毫秒,记录总数为" 
					+ totalCount + "。建议只获取指定的数据,务须统计总数。可调用setCountRecord(false);方法达到目的");
		}
		return totalCount;
	}
	
	/**
	 * 设置CallableStatement的参数
	 */
	private void setStatementValues(CallableStatement cs, Object[] args) {
		if ( args != null) {
			try {
				for (int i = 0; i < args.length; i++) {
					StatementCreatorUtils.setParameterValue(cs, i + 1, SqlTypeValue.TYPE_UNKNOWN, null, args[i]);
				}
			} catch (SQLException e) {
				logger.error(e.getMessage());
				throw new DataAccessResourceFailureException( e.getMessage() );
			}
		}
	}//~ setPreparedStatementValues
	
}

⌨️ 快捷键说明

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