/** * 游标协定以使用Iterator延迟处理获取行数据。 * 游标非常适合处理通常不适合内存的数百万个项目查询。 * 如果在resultMaps中使用集合,则必须使用resultMap的id列对游标SQL查询进行排序(resultOrdered =“ true”)。 * Cursor contract to handle fetching items lazily using an Iterator. * Cursors are a perfect fit to handle millions of items queries that would not normally fits in memory. * If you use collections in resultMaps then cursor SQL queries must be ordered (resultOrdered="true") * using the id columns of the resultMap. * * @author Guillaume Darmont / guillaume@dropinocean.com */ publicinterfaceCursor<T> extendsCloseable, Iterable<T> {
/** * 如果游标已开始从数据库中获取项目,则返回true * @return true if the cursor has started to fetch items from database. */ booleanisOpen();
/** * 如果游标已被完全消耗,并且已返回所有与查询匹配的元素,则返回true。 * @return true if the cursor is fully consumed and has returned all elements matching the query. */ booleanisConsumed();
/** * 获取当前项目索引。第一项的索引为0。 * Get the current item index. The first item has the index 0. * * @return -1 if the first cursor item has not been retrieved. The index of the current item retrieved. */ intgetCurrentIndex(); }
/** * This is the default implementation of a MyBatis Cursor. * This implementation is not thread safe. * * @author Guillaume Darmont / guillaume@dropinocean.com */ publicclassDefaultCursor<T> implementsCursor<T> {
/** * 新创建的游标,数据库ResultSet还未被消费 * A freshly created cursor, database ResultSet consuming has not started. */ CREATED, /** * 当前正在使用的游标已开始消费数据库ResultSet * A cursor currently in use, database ResultSet consuming has started. */ OPEN, /** * 游标已被关闭,未完全消费掉 * A closed cursor, not fully consumed. */ CLOSED, /** * 一个完全消费掉的游标,一个消费完的游标总是关闭的。 * A fully consumed cursor, a consumed cursor is always closed. */ CONSUMED }
/** * 获取迭代器 * @return */ @Override public Iterator<T> iterator(){ if (iteratorRetrieved) { thrownew IllegalStateException("Cannot open more than one iterator on a Cursor"); } if (isClosed()) { thrownew IllegalStateException("A Cursor is already closed."); } iteratorRetrieved = true; return cursorIterator; }
protected T fetchNextUsingRowBound(){ T result = fetchNextObjectFromDatabase(); // 过滤到偏移量的位置 while (objectWrapperResultHandler.fetched && indexWithRowBound < rowBounds.getOffset()) { result = fetchNextObjectFromDatabase(); } return result; }