-
Notifications
You must be signed in to change notification settings - Fork 13k
Cursor list implementation #52
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 allows MyBatis to return immediately from a selectList() call, returning a list that will fetch 'ondemand' elements database This behavior is especially usefull to implement functionnality such a "MyBatisCursorItemReader" in MyBatis Spring. * The returned list keeps an open connection, that should be explicitely closed by MyBatis client, using CursorList#closeResultSetAndStatement()
|
You need to use an implementation of the interface ResultHandler. public interface AbonentMapper {
// <select id="findAbonents" resultMap="abonentMap">SELECT * FROM ABONENTS</select>
void findAbonents(ResultHandler handler);
}
public class ProviderAbonentsImpl {
private void fetchAbonents(SqlSession sqlSession) {
AbonentMapper mapper = sqlSession.getMapper(AbonentMapper.class);
mapper.findAbonents(new AbonentHandler());
}
private class AbonentHandler implements ResultHandler {
@Override
public void handleResult(ResultContext context) {
Abonent abonent = (Abonent) context.getResultObject();
...
}
}
} |
|
It is a very nice feature to have for processing large result set as stream. |
|
+1 for that PR because ResultHandler is push type of data passing, where above cursor list implementation gives us pull. So you can easily pass an iterator to higher app tiers without introducing custom callback wrappers. However I don't like the way to solely count on user closing the cursor in the middle. This could be hooked somehow to session closing routine. Similarly as Hibernate is doing that with ScrollableResults. |
|
Iterator from list not solve the problem stop fetch data. We have to create your own interface from "Itarable". Add method of stopping the cycle. |
|
The proposed From what I've seen @pgaertig Agreed on the fact that the close could be handled by |
|
Usually use Processing RowBounds.limit guaranteed closes ResultSet and Statemet. Another example. Method Example of using JTA in Camel Java DSL: from("file:{{scanPath}}")
.transaction("required")
.split().method(new ReadSplitter(), "read").stream()
.filter().method(new DataFilter(), "filter")
.process(new StoreProcess())
.end()
.end();What gives Do you think many will remember that |
|
Be sure I know all of these considerations. The implementation is currently used in a JTA environment with 2 JDBC datasources and several JMS queues, without any problem. The only reason I made a One thing is sure : a cursor behavior is a real need, whatever the implementation provided. I hope it will be added in MyBatis (using this PR or from a more global rework) |
|
Hi Guillaume, In the last version we released we are still stabilizing 3.2.x. I do not think we need to go so far as 4.0 to add new methods to SqlSesion. 3.3 is ok for that as long as we just break "implementors". So feel free to add them. |
|
Implementing Iterable very useful. For Postgresql and etc Here are my sketches of the future functional cursor |
|
@gdarmont Next version will be 3.3.0. It is ok to introduce new methods to SqlSession. Can you please update the PR? Thanks in advance! |
|
@emacarron I won't have enough time right now to update the PR, though this is definitely something I have in mind. |
|
Hi @gdarmont No hurry at all. We are volunteers and there are no ETAs to fulfill at all. (This probably explains why it took us 9 months to pay attention to this enhacement). |
|
@emacarron, when 3.3 release and include such useful feature. |
|
Closing this PR as the feature has been reworked in PR #437 |
* modify to use Cursor.class.isAssignableFrom(Class<?>) * modfiy to use ExceptionFactory.wrapException(String,Exception) * modify copyright year
|
This new feature is great 👍 |
|
Yep. So do I. We will need some docs first otherwise very few people may get to this new feature. BTW people in this thread @alexey-su @fengxx @pgaertig @bwzhang2011 can you please have a look at the latest @gdarmont 's PR and post your thoughts?? (please go #437) |
Hi mybatis dev team,
I don’t know if creating directly a pull request is the right way to submit a feature for MyBatis, or if there’s another workflow. If so, please let me know.
This PR adds a feature which is needed to implement a MyBatisCursorItemReader for Spring Batch (see mybatis/spring#8 )
The feature allows SqlSession.selectList() to return a custom list implementation (CursorList) that will fetch item “on demand” while iterating over.
CursorList does not retain any fetched element, so it is a perfect choice for iterating over a ResultSet with several millions rows, without exhausting memory.
The drawback is that one can only iterate one time over a CursorList.
If several iterations over the list are needed, LazyList is available. It’s a simple wrapper over CursorList that keeps already fetched elements in a local storage.
Since CursorList fetches elements on demand, it needs to keep the ResultSql open. It’s automatically close when ResultSet is fully consumed. If resultset is partially consumed, it’s user responsability to close CursorList correctly using CursorList#closeResultSetAndStatement().
Usage :
XML mapping :
Java code :
Best regards,
Guillaume