Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit aa67be6

Browse files
committed
Support Stream as mapper method return type
Signed-off-by: Yanming Zhou <zhouyanming@gmail.com>
1 parent ed55127 commit aa67be6

File tree

8 files changed

+236
-2
lines changed

8 files changed

+236
-2
lines changed

‎src/main/java/org/apache/ibatis/binding/MapperMethod.java‎

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2009-2024 the original author or authors.
2+
* Copyright 2009-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -23,6 +23,10 @@
2323
import java.util.List;
2424
import java.util.Map;
2525
import java.util.Optional;
26+
import java.util.Spliterator;
27+
import java.util.Spliterators;
28+
import java.util.stream.Stream;
29+
import java.util.stream.StreamSupport;
2630

2731
import org.apache.ibatis.annotations.Flush;
2832
import org.apache.ibatis.annotations.MapKey;
@@ -43,6 +47,7 @@
4347
* @author Eduardo Macarron
4448
* @author Lasse Voss
4549
* @author Kazuki Shimizu
50+
* @author Yanming Zhou
4651
*/
4752
public class MapperMethod {
4853

@@ -82,6 +87,9 @@ public Object execute(SqlSession sqlSession, Object[] args) {
8287
result = executeForMap(sqlSession, args);
8388
} else if (method.returnsCursor()) {
8489
result = executeForCursor(sqlSession, args);
90+
} else if (method.returnsStream()) {
91+
Cursor<?> cursor = executeForCursor(sqlSession, args);
92+
result = StreamSupport.stream(Spliterators.spliteratorUnknownSize(cursor.iterator(), Spliterator.ORDERED), false);
8593
} else {
8694
Object param = method.convertArgsToSqlCommandParam(args);
8795
result = sqlSession.selectOne(command.getName(), param);
@@ -274,6 +282,7 @@ public static class MethodSignature {
274282
private final boolean returnsMap;
275283
private final boolean returnsVoid;
276284
private final boolean returnsCursor;
285+
private final boolean returnsStream;
277286
private final boolean returnsOptional;
278287
private final Class<?> returnType;
279288
private final String mapKey;
@@ -293,6 +302,7 @@ public MethodSignature(Configuration configuration, Class<?> mapperInterface, Me
293302
this.returnsVoid = void.class.equals(this.returnType);
294303
this.returnsMany = configuration.getObjectFactory().isCollection(this.returnType) || this.returnType.isArray();
295304
this.returnsCursor = Cursor.class.equals(this.returnType);
305+
this.returnsStream = Stream.class.equals(this.returnType);
296306
this.returnsOptional = Optional.class.equals(this.returnType);
297307
this.mapKey = getMapKey(method);
298308
this.returnsMap = this.mapKey != null;
@@ -341,6 +351,10 @@ public boolean returnsCursor() {
341351
return returnsCursor;
342352
}
343353

354+
public boolean returnsStream() {
355+
return returnsStream;
356+
}
357+
344358
/**
345359
* return whether return type is {@code java.util.Optional}.
346360
*

‎src/main/java/org/apache/ibatis/builder/annotation/MapperAnnotationBuilder.java‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@
9393
/**
9494
* @author Clinton Begin
9595
* @author Kazuki Shimizu
96+
* @author Yanming Zhou
9697
*/
9798
public class MapperAnnotationBuilder {
9899

@@ -401,7 +402,7 @@ private static Class<?> getReturnType(Method method, Class<?> type) {
401402
} else if (resolvedReturnType instanceof ParameterizedType) {
402403
ParameterizedType parameterizedType = (ParameterizedType) resolvedReturnType;
403404
Class<?> rawType = (Class<?>) parameterizedType.getRawType();
404-
if (Collection.class.isAssignableFrom(rawType) || Cursor.class.isAssignableFrom(rawType)) {
405+
if (Collection.class.isAssignableFrom(rawType) || Cursor.class.isAssignableFrom(rawType) || Stream.class.isAssignableFrom(rawType)) {
405406
Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
406407
if (actualTypeArguments != null && actualTypeArguments.length == 1) {
407408
Type returnTypeParameter = actualTypeArguments[0];
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
* Copyright 2009-2022 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.apache.ibatis.submitted.stream_on_mapper_method;
17+
18+
import org.apache.ibatis.annotations.Select;
19+
20+
import java.util.stream.Stream;
21+
22+
public interface Mapper {
23+
24+
@Select("select * from users order by id")
25+
Stream<User> findAll();
26+
27+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*
2+
* Copyright 2009-2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.apache.ibatis.submitted.stream_on_mapper_method;
17+
18+
import org.apache.ibatis.BaseDataTest;
19+
import org.apache.ibatis.io.Resources;
20+
import org.apache.ibatis.session.SqlSession;
21+
import org.apache.ibatis.session.SqlSessionFactory;
22+
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
23+
import org.junit.jupiter.api.BeforeAll;
24+
import org.junit.jupiter.api.Test;
25+
26+
import java.io.Reader;
27+
import java.util.stream.Stream;
28+
29+
import static org.junit.jupiter.api.Assertions.assertEquals;
30+
31+
/**
32+
* Tests for support the {@code java.util.stream.Stream} as return type of mapper method.
33+
*
34+
* @author Yanming Zhou
35+
*/
36+
class StreamOnMapperMethodTest {
37+
38+
private static SqlSessionFactory sqlSessionFactory;
39+
40+
@BeforeAll
41+
static void setUp() throws Exception {
42+
// create an SqlSessionFactory
43+
try (Reader reader = Resources
44+
.getResourceAsReader("org/apache/ibatis/submitted/stream_on_mapper_method/mybatis-config.xml")) {
45+
sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
46+
}
47+
48+
// populate in-memory database
49+
BaseDataTest.runScript(sqlSessionFactory.getConfiguration().getEnvironment().getDataSource(),
50+
"org/apache/ibatis/submitted/stream_on_mapper_method/CreateDB.sql");
51+
}
52+
53+
@Test
54+
void returnStream() {
55+
try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
56+
Mapper mapper = sqlSession.getMapper(Mapper.class);
57+
Stream<User> stream = mapper.findAll();
58+
assertEquals(2, stream.count());
59+
}
60+
}
61+
62+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* Copyright 2009-2022 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.apache.ibatis.submitted.stream_on_mapper_method;
17+
18+
public class User {
19+
20+
private Integer id;
21+
private String name;
22+
23+
public Integer getId() {
24+
return id;
25+
}
26+
27+
public void setId(Integer id) {
28+
this.id = id;
29+
}
30+
31+
public String getName() {
32+
return name;
33+
}
34+
35+
public void setName(String name) {
36+
this.name = name;
37+
}
38+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
--
2+
-- Copyright 2009-2022 the original author or authors.
3+
--
4+
-- Licensed under the Apache License, Version 2.0 (the "License");
5+
-- you may not use this file except in compliance with the License.
6+
-- You may obtain a copy of the License at
7+
--
8+
-- https://www.apache.org/licenses/LICENSE-2.0
9+
--
10+
-- Unless required by applicable law or agreed to in writing, software
11+
-- distributed under the License is distributed on an "AS IS" BASIS,
12+
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
-- See the License for the specific language governing permissions and
14+
-- limitations under the License.
15+
--
16+
17+
drop table users if exists;
18+
19+
create table users (
20+
id int,
21+
name varchar(20)
22+
);
23+
24+
insert into users (id, name) values
25+
(1, 'User1'), (2, 'User2');
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
4+
Copyright 2009-2022 the original author or authors.
5+
6+
Licensed under the Apache License, Version 2.0 (the "License");
7+
you may not use this file except in compliance with the License.
8+
You may obtain a copy of the License at
9+
10+
https://www.apache.org/licenses/LICENSE-2.0
11+
12+
Unless required by applicable law or agreed to in writing, software
13+
distributed under the License is distributed on an "AS IS" BASIS,
14+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
See the License for the specific language governing permissions and
16+
limitations under the License.
17+
18+
-->
19+
<!DOCTYPE mapper
20+
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
21+
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
22+
23+
<mapper namespace="org.apache.ibatis.submitted.stream_on_mapper_method.Mapper">
24+
25+
</mapper>
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
<!--
3+
4+
Copyright 2009-2022 the original author or authors.
5+
6+
Licensed under the Apache License, Version 2.0 (the "License");
7+
you may not use this file except in compliance with the License.
8+
You may obtain a copy of the License at
9+
10+
https://www.apache.org/licenses/LICENSE-2.0
11+
12+
Unless required by applicable law or agreed to in writing, software
13+
distributed under the License is distributed on an "AS IS" BASIS,
14+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
See the License for the specific language governing permissions and
16+
limitations under the License.
17+
18+
-->
19+
<!DOCTYPE configuration
20+
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
21+
"https://mybatis.org/dtd/mybatis-3-config.dtd">
22+
23+
<configuration>
24+
25+
<environments default="development">
26+
<environment id="development">
27+
<transactionManager type="JDBC">
28+
<property name="" value="" />
29+
</transactionManager>
30+
<dataSource type="UNPOOLED">
31+
<property name="driver" value="org.hsqldb.jdbcDriver" />
32+
<property name="url" value="jdbc:hsqldb:mem:useactualparamname" />
33+
<property name="username" value="sa" />
34+
</dataSource>
35+
</environment>
36+
</environments>
37+
38+
<mappers>
39+
<mapper class="org.apache.ibatis.submitted.stream_on_mapper_method.Mapper" />
40+
</mappers>
41+
42+
</configuration>

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /