Skip to content

Commit 3663aa6

Browse files
committed
GenericSqlQuery configured with RowMapper instance
Issue: SPR-14489 (cherry picked from commit 7287bae)
1 parent 1ca4b81 commit 3663aa6

File tree

3 files changed

+72
-27
lines changed

3 files changed

+72
-27
lines changed
Lines changed: 34 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2012 the original author or authors.
2+
* Copyright 2002-2016 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.
@@ -18,43 +18,57 @@
1818

1919
import java.util.Map;
2020

21-
import org.springframework.dao.InvalidDataAccessResourceUsageException;
21+
import org.springframework.beans.BeanUtils;
2222
import org.springframework.jdbc.core.RowMapper;
2323
import org.springframework.util.Assert;
2424

25+
/**
26+
* A concrete variant of {@link SqlQuery} which can be configured
27+
* with a {@link RowMapper}.
28+
*
29+
* @author Thomas Risberg
30+
* @author Juergen Hoeller
31+
* @since 3.0
32+
* @see #setRowMapper
33+
* @see #setRowMapperClass
34+
*/
2535
public class GenericSqlQuery<T> extends SqlQuery<T> {
2636

27-
Class<?> rowMapperClass;
37+
private RowMapper<T> rowMapper;
38+
39+
@SuppressWarnings("rawtypes")
40+
private Class<? extends RowMapper> rowMapperClass;
41+
2842

29-
RowMapper<?> rowMapper;
43+
/**
44+
* Set a specific {@link RowMapper} instance to use for this query.
45+
* @since 4.3.2
46+
*/
47+
public void setRowMapper(RowMapper<T> rowMapper) {
48+
this.rowMapper = rowMapper;
49+
}
3050

51+
/**
52+
* Set a {@link RowMapper} class for this query, creating a fresh
53+
* {@link RowMapper} instance per execution.
54+
*/
3155
@SuppressWarnings("rawtypes")
32-
public void setRowMapperClass(Class<? extends RowMapper> rowMapperClass)
33-
throws IllegalAccessException, InstantiationException {
56+
public void setRowMapperClass(Class<? extends RowMapper> rowMapperClass) {
3457
this.rowMapperClass = rowMapperClass;
35-
if (!RowMapper.class.isAssignableFrom(rowMapperClass))
36-
throw new IllegalStateException("The specified class '" +
37-
rowMapperClass.getName() + " is not a sub class of " +
38-
"'org.springframework.jdbc.core.RowMapper'");
3958
}
4059

4160
@Override
4261
public void afterPropertiesSet() {
4362
super.afterPropertiesSet();
44-
Assert.notNull(rowMapperClass, "The 'rowMapperClass' property is required");
63+
Assert.isTrue(this.rowMapper != null || this.rowMapperClass != null,
64+
"'rowMapper' or 'rowMapperClass' is required");
4565
}
4666

67+
4768
@Override
4869
@SuppressWarnings("unchecked")
4970
protected RowMapper<T> newRowMapper(Object[] parameters, Map<?, ?> context) {
50-
try {
51-
return (RowMapper<T>) rowMapperClass.newInstance();
52-
}
53-
catch (InstantiationException e) {
54-
throw new InvalidDataAccessResourceUsageException("Unable to instantiate RowMapper", e);
55-
}
56-
catch (IllegalAccessException e) {
57-
throw new InvalidDataAccessResourceUsageException("Unable to instantiate RowMapper", e);
58-
}
71+
return (this.rowMapper != null ? this.rowMapper : BeanUtils.instantiateClass(this.rowMapperClass));
5972
}
73+
6074
}

spring-jdbc/src/test/java/org/springframework/jdbc/object/GenericSqlQueryTests.java

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2014 the original author or authors.
2+
* Copyright 2002-2016 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.
@@ -16,7 +16,6 @@
1616

1717
package org.springframework.jdbc.object;
1818

19-
2019
import java.sql.Connection;
2120
import java.sql.PreparedStatement;
2221
import java.sql.ResultSet;
@@ -43,11 +42,12 @@
4342

4443
/**
4544
* @author Thomas Risberg
45+
* @author Juergen Hoeller
4646
*/
4747
public class GenericSqlQueryTests {
4848

4949
private static final String SELECT_ID_FORENAME_NAMED_PARAMETERS_PARSED =
50-
"select id, forename from custmr where id = ? and country = ?";
50+
"select id, forename from custmr where id = ? and country = ?";
5151

5252
private BeanFactory beanFactory;
5353

@@ -57,6 +57,7 @@ public class GenericSqlQueryTests {
5757

5858
private ResultSet resultSet;
5959

60+
6061
@Before
6162
public void setUp() throws Exception {
6263
this.beanFactory = new DefaultListableBeanFactory();
@@ -72,17 +73,23 @@ public void setUp() throws Exception {
7273
}
7374

7475
@Test
75-
public void testPlaceHoldersCustomerQuery() throws SQLException {
76-
SqlQuery<?> query = (SqlQuery<?>) beanFactory.getBean("queryWithPlaceHolders");
76+
public void testCustomerQueryWithPlaceholders() throws SQLException {
77+
SqlQuery<?> query = (SqlQuery<?>) beanFactory.getBean("queryWithPlaceholders");
7778
doTestCustomerQuery(query, false);
7879
}
7980

8081
@Test
81-
public void testNamedParameterCustomerQuery() throws SQLException {
82+
public void testCustomerQueryWithNamedParameters() throws SQLException {
8283
SqlQuery<?> query = (SqlQuery<?>) beanFactory.getBean("queryWithNamedParameters");
8384
doTestCustomerQuery(query, true);
8485
}
8586

87+
@Test
88+
public void testCustomerQueryWithRowMapperInstance() throws SQLException {
89+
SqlQuery<?> query = (SqlQuery<?>) beanFactory.getBean("queryWithRowMapperBean");
90+
doTestCustomerQuery(query, true);
91+
}
92+
8693
private void doTestCustomerQuery(SqlQuery<?> query, boolean namedParameters) throws SQLException {
8794
given(resultSet.next()).willReturn(true);
8895
given(resultSet.getInt("id")).willReturn(1);

spring-jdbc/src/test/resources/org/springframework/jdbc/object/GenericSqlQueryTests-context.xml

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
<bean id="dataSource" class="org.springframework.jdbc.datasource.TestDataSourceWrapper"/>
88

9-
<bean id="queryWithPlaceHolders" class="org.springframework.jdbc.object.GenericSqlQuery">
9+
<bean id="queryWithPlaceholders" class="org.springframework.jdbc.object.GenericSqlQuery">
1010
<property name="dataSource" ref="dataSource"/>
1111
<property name="sql" value="select id, forename from custmr where id = ? and country = ?"/>
1212
<property name="parameters">
@@ -50,4 +50,28 @@
5050
<property name="rowMapperClass" value="org.springframework.jdbc.object.CustomerMapper"/>
5151
</bean>
5252

53+
<bean id="queryWithRowMapperBean" class="org.springframework.jdbc.object.GenericSqlQuery">
54+
<property name="dataSource" ref="dataSource"/>
55+
<property name="sql" value="select id, forename from custmr where id = :id and country = :country"/>
56+
<property name="parameters">
57+
<list>
58+
<bean class="org.springframework.jdbc.core.SqlParameter">
59+
<constructor-arg index="0" value="id"/>
60+
<constructor-arg index="1">
61+
<util:constant static-field="java.sql.Types.INTEGER"/>
62+
</constructor-arg>
63+
</bean>
64+
<bean class="org.springframework.jdbc.core.SqlParameter">
65+
<constructor-arg index="0" value="country"/>
66+
<constructor-arg index="1">
67+
<util:constant static-field="java.sql.Types.VARCHAR"/>
68+
</constructor-arg>
69+
</bean>
70+
</list>
71+
</property>
72+
<property name="rowMapper">
73+
<bean class="org.springframework.jdbc.object.CustomerMapper"/>
74+
</property>
75+
</bean>
76+
5377
</beans>

0 commit comments

Comments
 (0)