From 23eb0e31289f47f8f369a7c6028fa0021989e692 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Tue, 25 Jul 2023 19:12:07 +0200 Subject: [PATCH] Polishing (cherry picked from commit bbde68c49e66c3c531920cb80a55742262507be7) --- .../jdbc/core/JdbcOperations.java | 7 ++-- .../jdbc/core/JdbcTemplate.java | 10 ++--- .../BeanPropertySqlParameterSource.java | 7 ++-- .../NamedParameterJdbcTemplate.java | 11 +++-- .../namedparam/NamedParameterQueryTests.java | 42 +++++++------------ 5 files changed, 35 insertions(+), 42 deletions(-) diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/JdbcOperations.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/JdbcOperations.java index 75937f348bb..7af681f52b4 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/JdbcOperations.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/JdbcOperations.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 the original author or authors. + * Copyright 2002-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -35,12 +35,13 @@ import org.springframework.lang.Nullable; *

Alternatively, the standard JDBC infrastructure can be mocked. * However, mocking this interface constitutes significantly less work. * As an alternative to a mock objects approach to testing data access code, - * consider the powerful integration testing support provided via the Spring - * TestContext Framework, in the {@code spring-test} artifact. + * consider the powerful integration testing support provided via the + * Spring TestContext Framework, in the {@code spring-test} artifact. * * @author Rod Johnson * @author Juergen Hoeller * @see JdbcTemplate + * @see org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations */ public interface JdbcOperations { diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/JdbcTemplate.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/JdbcTemplate.java index eb0fb2475bc..335a96022a6 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/JdbcTemplate.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/JdbcTemplate.java @@ -65,8 +65,7 @@ import org.springframework.util.StringUtils; * It executes core JDBC workflow, leaving application code to provide SQL * and extract results. This class executes SQL queries or updates, initiating * iteration over ResultSets and catching JDBC exceptions and translating - * them to the generic, more informative exception hierarchy defined in the - * {@code org.springframework.dao} package. + * them to the common {@code org.springframework.dao} exception hierarchy. * *

Code using this class need only implement callback interfaces, giving * them a clearly defined contract. The {@link PreparedStatementCreator} callback @@ -75,7 +74,8 @@ import org.springframework.util.StringUtils; * values from a ResultSet. See also {@link PreparedStatementSetter} and * {@link RowMapper} for two popular alternative callback interfaces. * - *

Can be used within a service implementation via direct instantiation + *

An instance of this template class is thread-safe once configured. + * Can be used within a service implementation via direct instantiation * with a DataSource reference, or get prepared in an application context * and given to services as bean reference. Note: The DataSource should * always be configured as a bean in the application context, in the first case @@ -88,12 +88,11 @@ import org.springframework.util.StringUtils; *

All SQL operations performed by this class are logged at debug level, * using "org.springframework.jdbc.core.JdbcTemplate" as log category. * - *

NOTE: An instance of this class is thread-safe once configured. - * * @author Rod Johnson * @author Juergen Hoeller * @author Thomas Risberg * @since May 3, 2001 + * @see JdbcOperations * @see PreparedStatementCreator * @see PreparedStatementSetter * @see CallableStatementCreator @@ -103,6 +102,7 @@ import org.springframework.util.StringUtils; * @see RowCallbackHandler * @see RowMapper * @see org.springframework.jdbc.support.SQLExceptionTranslator + * @see org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate */ public class JdbcTemplate extends JdbcAccessor implements JdbcOperations { diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/namedparam/BeanPropertySqlParameterSource.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/namedparam/BeanPropertySqlParameterSource.java index 83b8edb24b9..be0233d47ce 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/namedparam/BeanPropertySqlParameterSource.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/namedparam/BeanPropertySqlParameterSource.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -32,9 +32,10 @@ import org.springframework.util.StringUtils; /** * {@link SqlParameterSource} implementation that obtains parameter values * from bean properties of a given JavaBean object. The names of the bean - * properties have to match the parameter names. + * properties have to match the parameter names. Supports components of + * record classes as well, with accessor methods matching parameter names. * - *

Uses a Spring BeanWrapper for bean property access underneath. + *

Uses a Spring {@link BeanWrapper} for bean property access underneath. * * @author Thomas Risberg * @author Juergen Hoeller diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/namedparam/NamedParameterJdbcTemplate.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/namedparam/NamedParameterJdbcTemplate.java index 3d3752b5bf5..3c404354471 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/namedparam/NamedParameterJdbcTemplate.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/namedparam/NamedParameterJdbcTemplate.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -55,16 +55,19 @@ import org.springframework.util.ConcurrentLruCache; * done at execution time. It also allows for expanding a {@link java.util.List} * of values to the appropriate number of placeholders. * - *

The underlying {@link org.springframework.jdbc.core.JdbcTemplate} is + *

An instance of this template class is thread-safe once configured. + * The underlying {@link org.springframework.jdbc.core.JdbcTemplate} is * exposed to allow for convenient access to the traditional * {@link org.springframework.jdbc.core.JdbcTemplate} methods. * - *

NOTE: An instance of this class is thread-safe once configured. - * * @author Thomas Risberg * @author Juergen Hoeller * @since 2.0 * @see NamedParameterJdbcOperations + * @see SqlParameterSource + * @see ResultSetExtractor + * @see RowCallbackHandler + * @see RowMapper * @see org.springframework.jdbc.core.JdbcTemplate */ public class NamedParameterJdbcTemplate implements NamedParameterJdbcOperations { diff --git a/spring-jdbc/src/test/java/org/springframework/jdbc/core/namedparam/NamedParameterQueryTests.java b/spring-jdbc/src/test/java/org/springframework/jdbc/core/namedparam/NamedParameterQueryTests.java index 1a2c6146990..8c47dcda143 100644 --- a/spring-jdbc/src/test/java/org/springframework/jdbc/core/namedparam/NamedParameterQueryTests.java +++ b/spring-jdbc/src/test/java/org/springframework/jdbc/core/namedparam/NamedParameterQueryTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -34,8 +34,6 @@ import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.springframework.jdbc.core.RowMapper; - import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.BDDMockito.given; @@ -135,8 +133,7 @@ public class NamedParameterQueryTests { } @Test - public void testQueryForListWithParamMapAndIntegerElementAndSingleRowAndColumn() - throws Exception { + public void testQueryForListWithParamMapAndIntegerElementAndSingleRowAndColumn() throws Exception { given(resultSet.getMetaData()).willReturn(resultSetMetaData); given(resultSet.next()).willReturn(true, false); given(resultSet.getInt(1)).willReturn(11); @@ -174,11 +171,10 @@ public class NamedParameterQueryTests { MapSqlParameterSource params = new MapSqlParameterSource(); params.addValue("id", 3); - Object o = template.queryForObject("SELECT AGE FROM CUSTMR WHERE ID = :id", - params, (RowMapper) (rs, rowNum) -> rs.getInt(1)); + Integer value = template.queryForObject("SELECT AGE FROM CUSTMR WHERE ID = :id", + params, (rs, rowNum) -> rs.getInt(1)); - boolean condition = o instanceof Integer; - assertThat(condition).as("Correct result type").isTrue(); + assertThat(value).isEqualTo(22); verify(connection).prepareStatement("SELECT AGE FROM CUSTMR WHERE ID = ?"); verify(preparedStatement).setObject(1, 3); } @@ -191,11 +187,10 @@ public class NamedParameterQueryTests { Map params = new HashMap<>(); params.put("id", 3); - Object o = template.queryForObject("SELECT AGE FROM CUSTMR WHERE ID = :id", + Integer value = template.queryForObject("SELECT AGE FROM CUSTMR WHERE ID = :id", params, Integer.class); - boolean condition = o instanceof Integer; - assertThat(condition).as("Correct result type").isTrue(); + assertThat(value).isEqualTo(22); verify(connection).prepareStatement("SELECT AGE FROM CUSTMR WHERE ID = ?"); verify(preparedStatement).setObject(1, 3); } @@ -208,30 +203,26 @@ public class NamedParameterQueryTests { MapSqlParameterSource params = new MapSqlParameterSource(); params.addValue("id", 3); - Object o = template.queryForObject("SELECT AGE FROM CUSTMR WHERE ID = :id", + Integer value = template.queryForObject("SELECT AGE FROM CUSTMR WHERE ID = :id", params, Integer.class); - boolean condition = o instanceof Integer; - assertThat(condition).as("Correct result type").isTrue(); + assertThat(value).isEqualTo(22); verify(connection).prepareStatement("SELECT AGE FROM CUSTMR WHERE ID = ?"); verify(preparedStatement).setObject(1, 3); } @Test public void testQueryForObjectWithParamMapAndList() throws Exception { - String sql = "SELECT AGE FROM CUSTMR WHERE ID IN (:ids)"; - String sqlToUse = "SELECT AGE FROM CUSTMR WHERE ID IN (?, ?)"; given(resultSet.getMetaData()).willReturn(resultSetMetaData); given(resultSet.next()).willReturn(true, false); given(resultSet.getInt(1)).willReturn(22); MapSqlParameterSource params = new MapSqlParameterSource(); params.addValue("ids", Arrays.asList(3, 4)); - Object o = template.queryForObject(sql, params, Integer.class); + Integer value = template.queryForObject("SELECT AGE FROM CUSTMR WHERE ID IN (:ids)", params, Integer.class); - boolean condition = o instanceof Integer; - assertThat(condition).as("Correct result type").isTrue(); - verify(connection).prepareStatement(sqlToUse); + assertThat(value).isEqualTo(22); + verify(connection).prepareStatement("SELECT AGE FROM CUSTMR WHERE ID IN (?, ?)"); verify(preparedStatement).setObject(1, 3); } @@ -246,14 +237,11 @@ public class NamedParameterQueryTests { l1.add(new Object[] {3, "Rod"}); l1.add(new Object[] {4, "Juergen"}); params.addValue("multiExpressionList", l1); - Object o = template.queryForObject( - "SELECT AGE FROM CUSTMR WHERE (ID, NAME) IN (:multiExpressionList)", + Integer value = template.queryForObject("SELECT AGE FROM CUSTMR WHERE (ID, NAME) IN (:multiExpressionList)", params, Integer.class); - boolean condition = o instanceof Integer; - assertThat(condition).as("Correct result type").isTrue(); - verify(connection).prepareStatement( - "SELECT AGE FROM CUSTMR WHERE (ID, NAME) IN ((?, ?), (?, ?))"); + assertThat(value).isEqualTo(22); + verify(connection).prepareStatement("SELECT AGE FROM CUSTMR WHERE (ID, NAME) IN ((?, ?), (?, ?))"); verify(preparedStatement).setObject(1, 3); }