论坛首页 Java企业应用论坛

关于ibatis进行物理游标分页

浏览 16145 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2007-10-30  
我的数据库是采用mssql2000
采用分页必定数据量比较大:
按照ibatis的自带的是缓存分页.如果一大的肯定内存吃不消. 但是可以采用queryForList,却得不到总记录数码相.
要得到总记录数,因此我采用物理游标进行分页.
功能:需要得到结果的记录数,显示每页几行

(1)定义一个接口Pager:
public interface Pager {
	//总共几行
	public int getRows();
	//存入一页的数据
	public List<Object> getList();
	
	public void setList(List<Object> list);
	
	public void setRows(int rows);
}


(2)Pager实现类PagerImpl
public class PagerImpl implements Pager {
	
	private List<Object> list = null;
	private int rows = 0;
	
	public List<Object> getList() {
		return list;
	}
	public void setList(List<Object> list) {
		this.list = list;
	}

	public int getRows() {
		return rows;
	}
	public void setRows(int rows) {
		this.rows = rows;
	}

}



(3)扩展ibatis自带接口 SqlMapExecutor

 
//skip 起启行,max每页几行
 Pager queryForPager(String id, Object parameterObject, int skip, int max) throws SQLException;

  Pager queryForPager(String id, Object parameterObject, int skip) throws SQLException;
  //根据条件查出所有结果
  Pager queryForPager(String id, Object parameterObject) throws SQLException;
  



(4)扩展ibatis接口 SqlMapExecutor的实现类有两个SqlMapClientImpl,SqlMapSessionImpl

SqlMapClientImpl的扩展如下
public Pager queryForPager(String id, Object paramObject, int skip, int max)
			throws SQLException {
		if (max <= 0)
			return getLocalSqlMapSession().queryForPager(id, paramObject, skip);
		else
			return getLocalSqlMapSession().queryForPager(id, paramObject, skip,
					max);
	}

	public Pager queryForPager(String id, Object parameterObject, int skip)
			throws SQLException {
		return getLocalSqlMapSession().queryForPager(id, parameterObject, skip,
				SqlExecutor.NO_MAXIMUM_RESULTS);
	}

	public Pager queryForPager(String id, Object parameterObject)
			throws SQLException {
		return getLocalSqlMapSession().queryForPager(id, parameterObject,
				SqlExecutor.NO_SKIPPED_RESULTS, SqlExecutor.NO_MAXIMUM_RESULTS);
	}



(5)最终修改SqlExecutor获取总记录数
SqlExecutor:439行
if (resultMap != null) {
				// Skip Results
				if (rs.getType() != ResultSet.TYPE_FORWARD_ONLY) {
					rs.beforeFirst();
					if (skipResults > 0) {
						rs.absolute(skipResults);
					}
				} else {
					for (int i = 0; i < skipResults; i++) {
						if (!rs.next()) {
							return;
						}
					}
				}

				// Get Results
				int resultsFetched = 0;
				while ((maxResults == SqlExecutor.NO_MAXIMUM_RESULTS || resultsFetched < maxResults)
						&& rs.next()) {
					Object[] columnValues = resultMap
							.resolveSubMap(request, rs).getResults(request, rs);
					callback.handleResultObject(request, columnValues, rs);
					resultsFetched++;
				}
				if (rs.getType() != ResultSet.TYPE_FORWARD_ONLY) {
					rs.last();
					request.setRows(rs.getRow());
				} else {
					int total = skipResults + resultsFetched;
					while(rs.next()){
						total++;
					}
					request.setRows(total);
				}
				
			}




这样就可以了

(6)如何调用
6.1创建一个方法
public static Pager pager(GroupVO vo,int offset,int limit)throws SQLException{
	  return sqlMapper.queryForPager("list",vo,offset);
  }


public static void main(String[] args){
	  try {
		SimpleExample se = new SimpleExample();
		GroupVO vo = new GroupVO();
		Pager pager = se.pager(vo,0,10);
		 //vo.setGroup_no("100");
		  //vo.setGroup_name("fengjian");
		  //vo.setGroup_desc("thanks");
		
		System.out.println("totalsize = "+pager.getRows());
		List list = pager.getList();
		if(list!=null)
			for(int i=0; i<list.size(); i++){
				GroupVO v = (GroupVO)list.get(i);
				System.out.println("group no = " + v.getGroup_no());
			}
		
	} catch (SQLException e) {
		e.printStackTrace();
	}
  }



有什么不同看法:msn:linuxfjy@hotmail.com, mail: kusoft@qq.com
   发表时间:2007-11-03  
详细demo:参照http://www.kusoft.net
0 请登录后投票
   发表时间:2007-11-03  
呵呵,思路与我现在的做法基本类似。
我是直接添加了一个PaginatedArrayList类,扩展ArrayList加上了count属性。


0 请登录后投票
   发表时间:2007-11-26  
这种做法无疑于自杀:
1、hack ibatis代码不可取。
2、最新的ibatis代码中已经不推荐使用queryForPager类似的方法。
3、建议使用db级的limit
0 请登录后投票
   发表时间:2007-11-26  
iBATIS已经不推荐使用queryForPager方法,大数据量的分页尽量使用数据库平台专有sql,如mysql的limit、oracle的rownm与窗口函数。
0 请登录后投票
   发表时间:2007-11-26  
淌汗。。。。。 你灌个几十几百万条记录,然后rs.last();一下看看,不outofmemory才怪。
0 请登录后投票
   发表时间:2007-11-30  
问一下,MSSQL2000如何做分页?
有人说,使用存储过程.但复杂的SQL查询语句.好像不行
0 请登录后投票
   发表时间:2008-06-08  
使用 rs.absolute(skipResults)
我真的不太清楚。大家如何使用 ibatis对 mssql2000数据库进行分页。又如何得到查询结果总记录数?
0 请登录后投票
   发表时间:2008-06-09  
其实MS SQL不会出现rs.last()后outofmemory的问题,除非你用的JDBC有问题,我使用用的MS SQL的JDBC中rs.last()只是把游标移动了一下,而有的数据库的JDBC是通过滚动的方式吧数据库的数据拿过来放内存,才会出现内存溢出,其实MS SQL分页效率最高的就是用rs的游标滚动,不过参数一定不要错了,而mysql最好的是用limit,sybase就只能使用一个很郁闷的方法,写存储过程来实现分页
0 请登录后投票
   发表时间:2008-06-09  
太麻烦了吧。sqlmap里加上limit #offset#,#limit#
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics