-
Notifications
You must be signed in to change notification settings - Fork 13k
Cursor implementation #437
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
This change is due to the introduction of new methods for Cursor handling in SqlSession interface
* Added new SqlSession methods selectCursor() * Cursors extends Iterable to be easily used with foreach Statement and implements Closeable to be used with try-with-resources in Java 7+ * Cursors are automatically closed when fully fetched or on SqlSession close This feature is useful to implement functionality such as the "MyBatisCursorItemReader" in MyBatis Spring.
|
Its been a long time @gdarmont but thank you very much for looking again into this. |
* modify to use Cursor.class.isAssignableFrom(Class<?>) * modfiy to use ExceptionFactory.wrapException(String,Exception) * modify copyright year
#437: Polishing some logics and comments
|
Hi @emacarron @gdarmont, protected T fetchNextUsingRowBound() {
T result = fetchNextObjectFromDatabase();
while (currentIndex < rowBounds.getOffset()) {
result = fetchNextObjectFromDatabase();
}
return result;
}Logic to skip records until offset is this ? |
|
What happens when you call again? Nose smell that fetchNextObjectFromDatabase method does not check the value of the attribute "opened". I stand by @kazuki43zoo. Your code is not optimal. Before the walk up to the first RowBounds.offset, you raise and lose a lot of objects. You do not take into account that could go ResultMap calls nested SQL queries. |
|
Hi all, Thanks for the feedback. I admit I did not make tests to handle corner cases, and as you mentioned there may be problems (several close() calls, not enough rows etc...). I think it is worth explaining the origin of Cursor : Requirement : SQL requests used with selectCursor() needs to be ordered (resultOrdered="true" in mapping), to allow intermediate result objects to be released (https://github.com/mybatis/mybatis-3/blob/master/src/main/java/org/apache/ibatis/executor/resultset/DefaultResultSetHandler.java#L771-L773), otherwise it wouldn't be very memory efficient for very large resultset. Result ordering is the only constraint that makes selectCursor() different from selectList(). RowBound part : The only reason I integrated a selectCursor() method taking a RowBound is to have a one to one Cursor equivalent to selectList(). Currently a RowBound unit (= value of 1) in MyBatis is mapped to a row in a ResultSet (a database row). The loop part is used to mimic the offset advance used in DefaultResultSetHandler : https://github.com/mybatis/mybatis-3/blob/master/src/main/java/org/apache/ibatis/executor/resultset/DefaultResultSetHandler.java#L348-350 . And since MyBatis can transform several rows into one "toplevel" object, I don't currently see how it could be more efficient. Of course, this triggers a lot of garbage since objects are created but never used. But it seems to me that RowBound in general is only here to ease life on few situations (since it can lead to wrong results, as seen above when we use nested collections mappings). A developer with performance concerns will craft the SQL request to only compute the needed data, and so, won't have the need of the RowBound feature. To sum up, here's a small todo list :
@alexey-su For the nested SQL queries, the current code simply rely on the core mapping features of MyBatis and as such, should handle them seamlessly. Do you have a reproduce test so that I can check on my side ? Hope this helps. |
Revert "#437: Polishing some logics and comments"
|
我用的3.4.2 cursor好像不起啥作用 |
Cursor list implementation
* modify to use Cursor.class.isAssignableFrom(Class<?>) * modfiy to use ExceptionFactory.wrapException(String,Exception) * modify copyright year
mybatis#437: Polishing some logics and comments
…ishing Revert "mybatis#437: Polishing some logics and comments"
Hi mybatis dev team,
Here's an up to date version of a minimalist Cursor implementation. This PR replaces the previous implementation I made in PR 52 (#52).
I bumped the version to 3.4.0-SNAPSHOT as SqlSession gets new methods.
This PR adds the Cursor feature which is needed to implement a MyBatisCursorItemReader for Spring Batch.
Features
A Cursor does not retain any fetched element, so it is a perfect choice for iterating over a ResultSet with several millions rows, without exhausting memory.
Usage :
XML mapping :
Java code :
Best regards,
Guillaume