Browse Source

JdbcTemplate's queryForObject allows for specifying primitive types as well

Issue: SPR-13220
pull/837/merge
Juergen Hoeller 11 years ago
parent
commit
e0329306df
  1. 14
      spring-jdbc/src/main/java/org/springframework/jdbc/core/BeanPropertyRowMapper.java
  2. 22
      spring-jdbc/src/main/java/org/springframework/jdbc/core/SingleColumnRowMapper.java
  3. 35
      spring-jdbc/src/test/java/org/springframework/jdbc/core/JdbcTemplateQueryTests.java

14
spring-jdbc/src/main/java/org/springframework/jdbc/core/BeanPropertyRowMapper.java

@ -92,7 +92,7 @@ public class BeanPropertyRowMapper<T> implements RowMapper<T> {
/** /**
* Create a new BeanPropertyRowMapper for bean-style configuration. * Create a new {@code BeanPropertyRowMapper} for bean-style configuration.
* @see #setMappedClass * @see #setMappedClass
* @see #setCheckFullyPopulated * @see #setCheckFullyPopulated
*/ */
@ -100,8 +100,8 @@ public class BeanPropertyRowMapper<T> implements RowMapper<T> {
} }
/** /**
* Create a new BeanPropertyRowMapper, accepting unpopulated properties * Create a new {@code BeanPropertyRowMapper}, accepting unpopulated
* in the target bean. * properties in the target bean.
* <p>Consider using the {@link #newInstance} factory method instead, * <p>Consider using the {@link #newInstance} factory method instead,
* which allows for specifying the mapped type once only. * which allows for specifying the mapped type once only.
* @param mappedClass the class that each row should be mapped to * @param mappedClass the class that each row should be mapped to
@ -111,7 +111,7 @@ public class BeanPropertyRowMapper<T> implements RowMapper<T> {
} }
/** /**
* Create a new BeanPropertyRowMapper. * Create a new {@code BeanPropertyRowMapper}.
* @param mappedClass the class that each row should be mapped to * @param mappedClass the class that each row should be mapped to
* @param checkFullyPopulated whether we're strictly validating that * @param checkFullyPopulated whether we're strictly validating that
* all bean properties have been mapped from corresponding database fields * all bean properties have been mapped from corresponding database fields
@ -326,14 +326,12 @@ public class BeanPropertyRowMapper<T> implements RowMapper<T> {
/** /**
* Static factory method to create a new BeanPropertyRowMapper * Static factory method to create a new {@code BeanPropertyRowMapper}
* (with the mapped class specified only once). * (with the mapped class specified only once).
* @param mappedClass the class that each row should be mapped to * @param mappedClass the class that each row should be mapped to
*/ */
public static <T> BeanPropertyRowMapper<T> newInstance(Class<T> mappedClass) { public static <T> BeanPropertyRowMapper<T> newInstance(Class<T> mappedClass) {
BeanPropertyRowMapper<T> newInstance = new BeanPropertyRowMapper<T>(); return new BeanPropertyRowMapper<T>(mappedClass);
newInstance.setMappedClass(mappedClass);
return newInstance;
} }
} }

22
spring-jdbc/src/main/java/org/springframework/jdbc/core/SingleColumnRowMapper.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2014 the original author or authors. * Copyright 2002-2015 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -23,6 +23,7 @@ import java.sql.SQLException;
import org.springframework.dao.TypeMismatchDataAccessException; import org.springframework.dao.TypeMismatchDataAccessException;
import org.springframework.jdbc.IncorrectResultSetColumnCountException; import org.springframework.jdbc.IncorrectResultSetColumnCountException;
import org.springframework.jdbc.support.JdbcUtils; import org.springframework.jdbc.support.JdbcUtils;
import org.springframework.util.ClassUtils;
import org.springframework.util.NumberUtils; import org.springframework.util.NumberUtils;
/** /**
@ -41,31 +42,34 @@ import org.springframework.util.NumberUtils;
*/ */
public class SingleColumnRowMapper<T> implements RowMapper<T> { public class SingleColumnRowMapper<T> implements RowMapper<T> {
private Class<T> requiredType; private Class<?> requiredType;
/** /**
* Create a new SingleColumnRowMapper. * Create a new {@code SingleColumnRowMapper} for bean-style configuration.
* @see #setRequiredType * @see #setRequiredType
*/ */
public SingleColumnRowMapper() { public SingleColumnRowMapper() {
} }
/** /**
* Create a new SingleColumnRowMapper. * Create a new {@code SingleColumnRowMapper}.
* <p>Consider using the {@link #newInstance} factory method instead,
* which allows for specifying the required type once only.
* @param requiredType the type that each result object is expected to match * @param requiredType the type that each result object is expected to match
*/ */
public SingleColumnRowMapper(Class<T> requiredType) { public SingleColumnRowMapper(Class<T> requiredType) {
this.requiredType = requiredType; setRequiredType(requiredType);
} }
/** /**
* Set the type that each result object is expected to match. * Set the type that each result object is expected to match.
* <p>If not specified, the column value will be exposed as * <p>If not specified, the column value will be exposed as
* returned by the JDBC driver. * returned by the JDBC driver.
*/ */
public void setRequiredType(Class<T> requiredType) { public void setRequiredType(Class<T> requiredType) {
this.requiredType = requiredType; this.requiredType = ClassUtils.resolvePrimitiveIfNecessary(requiredType);
} }
@ -187,15 +191,13 @@ public class SingleColumnRowMapper<T> implements RowMapper<T> {
/** /**
* Static factory method to create a new ParameterizedSingleColumnRowMapper * Static factory method to create a new {@code SingleColumnRowMapper}
* (with the required type specified only once). * (with the required type specified only once).
* @param requiredType the type that each result object is expected to match * @param requiredType the type that each result object is expected to match
* @since 4.1 * @since 4.1
*/ */
public static <T> SingleColumnRowMapper<T> newInstance(Class<T> requiredType) { public static <T> SingleColumnRowMapper<T> newInstance(Class<T> requiredType) {
SingleColumnRowMapper<T> newInstance = new SingleColumnRowMapper<T>(); return new SingleColumnRowMapper<T>(requiredType);
newInstance.setRequiredType(requiredType);
return newInstance;
} }
} }

35
spring-jdbc/src/test/java/org/springframework/jdbc/core/JdbcTemplateQueryTests.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2014 the original author or authors. * Copyright 2002-2015 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -41,6 +41,7 @@ import static org.mockito.BDDMockito.*;
/** /**
* @author Juergen Hoeller * @author Juergen Hoeller
* @author Phillip Webb * @author Phillip Webb
* @author Rob Winch
* @since 19.12.2004 * @since 19.12.2004
*/ */
public class JdbcTemplateQueryTests { public class JdbcTemplateQueryTests {
@ -49,13 +50,20 @@ public class JdbcTemplateQueryTests {
public ExpectedException thrown = ExpectedException.none(); public ExpectedException thrown = ExpectedException.none();
private Connection connection; private Connection connection;
private DataSource dataSource; private DataSource dataSource;
private Statement statement; private Statement statement;
private PreparedStatement preparedStatement; private PreparedStatement preparedStatement;
private ResultSet resultSet; private ResultSet resultSet;
private ResultSetMetaData resultSetMetaData; private ResultSetMetaData resultSetMetaData;
private JdbcTemplate template; private JdbcTemplate template;
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
this.connection = mock(Connection.class); this.connection = mock(Connection.class);
@ -75,6 +83,7 @@ public class JdbcTemplateQueryTests {
given(this.statement.executeQuery(anyString())).willReturn(this.resultSet); given(this.statement.executeQuery(anyString())).willReturn(this.resultSet);
} }
@Test @Test
public void testQueryForList() throws Exception { public void testQueryForList() throws Exception {
String sql = "SELECT AGE FROM CUSTMR WHERE ID < 3"; String sql = "SELECT AGE FROM CUSTMR WHERE ID < 3";
@ -219,7 +228,18 @@ public class JdbcTemplateQueryTests {
String sql = "SELECT AGE FROM CUSTMR WHERE ID = 3"; String sql = "SELECT AGE FROM CUSTMR WHERE ID = 3";
given(this.resultSet.next()).willReturn(true, false); given(this.resultSet.next()).willReturn(true, false);
given(this.resultSet.getInt(1)).willReturn(22); given(this.resultSet.getInt(1)).willReturn(22);
int i = this.template.queryForObject(sql,Integer.class).intValue(); int i = this.template.queryForObject(sql, Integer.class).intValue();
assertEquals("Return of an int", 22, i);
verify(this.resultSet).close();
verify(this.statement).close();
}
@Test
public void testQueryForIntPrimitive() throws Exception {
String sql = "SELECT AGE FROM CUSTMR WHERE ID = 3";
given(this.resultSet.next()).willReturn(true, false);
given(this.resultSet.getInt(1)).willReturn(22);
int i = this.template.queryForObject(sql, int.class);
assertEquals("Return of an int", 22, i); assertEquals("Return of an int", 22, i);
verify(this.resultSet).close(); verify(this.resultSet).close();
verify(this.statement).close(); verify(this.statement).close();
@ -236,6 +256,17 @@ public class JdbcTemplateQueryTests {
verify(this.statement).close(); verify(this.statement).close();
} }
@Test
public void testQueryForLongPrimitive() throws Exception {
String sql = "SELECT AGE FROM CUSTMR WHERE ID = 3";
given(this.resultSet.next()).willReturn(true, false);
given(this.resultSet.getLong(1)).willReturn(87L);
long l = this.template.queryForObject(sql, long.class);
assertEquals("Return of a long", 87, l);
verify(this.resultSet).close();
verify(this.statement).close();
}
@Test @Test
public void testQueryForListWithArgs() throws Exception { public void testQueryForListWithArgs() throws Exception {
doTestQueryForListWithArgs("SELECT AGE FROM CUSTMR WHERE ID < ?"); doTestQueryForListWithArgs("SELECT AGE FROM CUSTMR WHERE ID < ?");

Loading…
Cancel
Save