Tagged: iterator

Using Cursors with MyBatis


There are queries that you shouldn’t map as List<T>.

And the Cursor comes to play.

@Service
public class SomeService {

    public Cursor<Some> getCursor(...) {
        // returns the cursor?
    }
}

Well it not a good way to do with it. The return value Cursor<Some>¬†won’t work because the session may already be finished when the method returns.

@Service
public class SomeService {

    @Transactional
    public <R> R applyCursor(
            ...,
            Function<Cursor<Some>, R> function) {
        final Cursor<Some> cursor = ...;
        return function.apply(cursor);
    }
}

Now we can add some other methods to do with it.

    public <R> R applyIterator(
            ...,
            Function<Iterator<Some>, R> function) {
        applyCursor(
                ...,
                cursor -> function.apply(cursor.iterator())
        );
    }

What about a Spliterator?

    public <R> R applySpliterator(
            ...,
            Function<Spliterator<Some>, R> function) {
        applyIterator(
                ...,
                iterator -> {
                    int characteristics
                        = Spliterator.DISTINCT
                          | Spliterator.IMMUTABLE
                          | Spliterator.NONNULL
                          | Spliterator.ORDERED;
                    Spliterator<CsEventAssociate> spliterator
                        = Spliterators.spliteratorUnknownSize(
                                iterator, characteristics);
                    return function.apply(spliterator);
                }
        );
    }

And the Stream?

    public <R> R applyStream(
            ...,
            Function<Stream<Some>, R> function) {
        return applySpliterator(
            ...,
            spliterator -> function.apply(StreamSupport.stream(spliterator, false))
        );
    }