Skip to content

Commit d9dffb9

Browse files
committed
RowMappers and ResultSetExtractors.
1 parent 2d1ed8a commit d9dffb9

File tree

6 files changed

+168
-3
lines changed

6 files changed

+168
-3
lines changed

spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/aot/JdbcCodeBlocks.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -578,11 +578,11 @@ public CodeBlock build() {
578578

579579
if (rowMapperClass != null) {
580580
builder.addStatement("$T $L = new $T()", RowMapper.class, rowMapper,
581-
context.fieldNameOf(RowMapperFactory.class), rowMapperClass);
581+
rowMapperClass);
582582
} else if (StringUtils.hasText(rowMapperRef)) {
583583
builder.addStatement("$T $L = $L.getRowMapper($S)", RowMapper.class, rowMapper,
584584
context.fieldNameOf(RowMapperFactory.class), rowMapperRef);
585-
} else {
585+
} else if (resultSetExtractorClass == null) {
586586
builder.addStatement("$T $L = $L.create($T.class)", RowMapper.class, rowMapper,
587587
context.fieldNameOf(RowMapperFactory.class), actualReturnType);
588588
}
@@ -593,7 +593,7 @@ public CodeBlock build() {
593593

594594
if (resultSetExtractorClass != null && (rowMapperClass != null || StringUtils.hasText(rowMapperRef))) {
595595
builder.addStatement("$T $L = new $T($L)", ResultSetExtractor.class, resultSetExtractor,
596-
resultSetExtractorClass, rowMapperRef);
596+
resultSetExtractorClass, rowMapper);
597597
} else if (resultSetExtractorClass != null) {
598598
builder.addStatement("$T $L = new $T()", ResultSetExtractor.class, resultSetExtractor,
599599
resultSetExtractorClass);

spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/aot/JdbcRepositoryContributorIntegrationTests.java

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,16 @@ TestClass testClass() {
7171
return TestClass.of(JdbcRepositoryContributorIntegrationTests.class);
7272
}
7373

74+
@Bean
75+
MyRowMapper myRowMapper() {
76+
return new MyRowMapper();
77+
}
78+
79+
@Bean
80+
SimpleResultSetExtractor simpleResultSetExtractor() {
81+
return new SimpleResultSetExtractor();
82+
}
83+
7484
}
7585

7686
@BeforeEach
@@ -228,6 +238,40 @@ void shouldFindAnnotatedByFirstnameExpression() {
228238
assertThat(walter.getFirstname()).isEqualTo("Walter");
229239
}
230240

241+
@Test // GH-2121
242+
void shouldFindUsingRowMapper() {
243+
244+
User walter = fragment.findUsingRowMapper("Walter");
245+
246+
assertThat(walter).isNotNull();
247+
assertThat(walter.getFirstname()).isEqualTo("Row: 0");
248+
}
249+
250+
@Test // GH-2121
251+
void shouldFindUsingRowMapperRef() {
252+
253+
User walter = fragment.findUsingRowMapperRef("Walter");
254+
255+
assertThat(walter).isNotNull();
256+
assertThat(walter.getFirstname()).isEqualTo("Row: 0");
257+
}
258+
259+
@Test // GH-2121
260+
void shouldFindUsingResultSetExtractor() {
261+
262+
int result = fragment.findUsingAndResultSetExtractor("Walter");
263+
264+
assertThat(result).isOne();
265+
}
266+
267+
@Test // GH-2121
268+
void shouldFindUsingResultSetExtractorRef() {
269+
270+
int result = fragment.findUsingAndResultSetExtractorRef("Walter");
271+
272+
assertThat(result).isOne();
273+
}
274+
231275
@Test // GH-2121
232276
void shouldDeleteByName() {
233277

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* Copyright 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.springframework.data.jdbc.repository.aot;
17+
18+
import java.sql.ResultSet;
19+
import java.sql.SQLException;
20+
21+
import org.springframework.dao.DataAccessException;
22+
import org.springframework.jdbc.core.ResultSetExtractor;
23+
import org.springframework.jdbc.core.RowMapper;
24+
25+
/**
26+
* @author Mark Paluch
27+
*/
28+
public class MyResultSetExtractor implements ResultSetExtractor<User> {
29+
30+
private final RowMapper<User> rowMapper;
31+
32+
public MyResultSetExtractor(RowMapper<User> rowMapper) {
33+
this.rowMapper = rowMapper;
34+
}
35+
36+
@Override
37+
public User extractData(ResultSet rs) throws SQLException, DataAccessException {
38+
return rs.next() ? rowMapper.mapRow(rs, 0) : null;
39+
}
40+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
* Copyright 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.springframework.data.jdbc.repository.aot;
17+
18+
import java.sql.ResultSet;
19+
20+
import org.springframework.jdbc.core.RowMapper;
21+
22+
/**
23+
* @author Mark Paluch
24+
*/
25+
public class MyRowMapper implements RowMapper<User> {
26+
27+
@Override
28+
public User mapRow(ResultSet rs, int rowNum) {
29+
return new User("Row: " + rowNum, rowNum);
30+
}
31+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
* Copyright 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.springframework.data.jdbc.repository.aot;
17+
18+
import java.sql.ResultSet;
19+
import java.sql.SQLException;
20+
21+
import org.springframework.dao.DataAccessException;
22+
import org.springframework.jdbc.core.ResultSetExtractor;
23+
24+
/**
25+
* @author Mark Paluch
26+
*/
27+
public class SimpleResultSetExtractor implements ResultSetExtractor<Integer> {
28+
29+
@Override
30+
public Integer extractData(ResultSet rs) throws SQLException, DataAccessException {
31+
return rs.next() ? 1 : 0;
32+
}
33+
}

spring-data-jdbc/src/test/java/org/springframework/data/jdbc/repository/aot/UserRepository.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,23 @@ public interface UserRepository extends CrudRepository<User, Integer> {
6969
@Query("SELECT * FROM MY_USER WHERE firstname = :#{#name}")
7070
User findByFirstnameExpression(String name);
7171

72+
@Query(value = "SELECT * FROM MY_USER WHERE firstname = :name", rowMapperClass = MyRowMapper.class)
73+
User findUsingRowMapper(String name);
74+
75+
@Query(value = "SELECT * FROM MY_USER WHERE firstname = :name", rowMapperClass = MyRowMapper.class,
76+
resultSetExtractorClass = MyResultSetExtractor.class)
77+
User findUsingRowMapperAndResultSetExtractor(String name);
78+
79+
@Query(value = "SELECT * FROM MY_USER WHERE firstname = :name", rowMapperRef = "myRowMapper")
80+
User findUsingRowMapperRef(String name);
81+
82+
@Query(value = "SELECT * FROM MY_USER WHERE firstname = :name",
83+
resultSetExtractorClass = SimpleResultSetExtractor.class)
84+
int findUsingAndResultSetExtractor(String name);
85+
86+
@Query(value = "SELECT * FROM MY_USER WHERE firstname = :name", resultSetExtractorRef = "simpleResultSetExtractor")
87+
int findUsingAndResultSetExtractorRef(String name);
88+
7289
// -------------------------------------------------------------------------
7390
// Parameter naming
7491
// -------------------------------------------------------------------------

0 commit comments

Comments
 (0)