From 7ab40982224aa77ff1f004c5a9ff3bfa738f9917 Mon Sep 17 00:00:00 2001 From: Mikhail2048 Date: Sun, 5 Feb 2023 16:52:47 +0300 Subject: [PATCH] Enhanced @Query documentation --- .../repository/query/AbstractJdbcQuery.java | 6 +---- .../repository/query/PartTreeJdbcQuery.java | 17 ++++++++++--- .../data/jdbc/repository/query/Query.java | 25 ++++++++++++------- .../query/StringBasedJdbcQuery.java | 23 +++++++++++------ 4 files changed, 47 insertions(+), 24 deletions(-) diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/AbstractJdbcQuery.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/AbstractJdbcQuery.java index 949d0d744b..05ea371bc2 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/AbstractJdbcQuery.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/AbstractJdbcQuery.java @@ -82,10 +82,6 @@ public JdbcQueryMethod getQueryMethod() { protected JdbcQueryExecution getQueryExecution(JdbcQueryMethod queryMethod, @Nullable ResultSetExtractor extractor, RowMapper rowMapper) { - if (queryMethod.isModifyingQuery()) { - return createModifyingQueryExecutor(); - } - if (queryMethod.isCollectionQuery()) { return extractor != null ? getQueryExecution(extractor) : collectionQuery(rowMapper); } @@ -97,7 +93,7 @@ protected JdbcQueryExecution getQueryExecution(JdbcQueryMethod queryMethod, return extractor != null ? getQueryExecution(extractor) : singleObjectQuery(rowMapper); } - private JdbcQueryExecution createModifyingQueryExecutor() { + protected JdbcQueryExecution createModifyingQueryExecutor() { return (query, parameters) -> { diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/PartTreeJdbcQuery.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/PartTreeJdbcQuery.java index 5487f147f7..1b674d4cf3 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/PartTreeJdbcQuery.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/PartTreeJdbcQuery.java @@ -43,6 +43,7 @@ import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations; import org.springframework.jdbc.core.namedparam.SqlParameterSource; +import org.springframework.lang.Nullable; import org.springframework.util.Assert; /** @@ -144,9 +145,7 @@ private JdbcQueryExecution getQueryExecution(ResultProcessor processor, resultProcessingConverter); } - JdbcQueryExecution queryExecution = getQueryMethod().isPageQuery() || getQueryMethod().isSliceQuery() - ? collectionQuery(rowMapper) - : getQueryExecution(getQueryMethod(), extractor, rowMapper); + JdbcQueryExecution queryExecution = getJdbcQueryExecution(extractor, rowMapper); if (getQueryMethod().isSliceQuery()) { return new SliceQueryExecution<>((JdbcQueryExecution>) queryExecution, accessor.getPageable()); @@ -173,6 +172,18 @@ private JdbcQueryExecution getQueryExecution(ResultProcessor processor, return queryExecution; } + private JdbcQueryExecution getJdbcQueryExecution(@Nullable ResultSetExtractor extractor, RowMapper rowMapper) { + if (getQueryMethod().isPageQuery() || getQueryMethod().isSliceQuery()) { + return collectionQuery(rowMapper); + } else { + if (getQueryMethod().isModifyingQuery()) { + return createModifyingQueryExecutor(); + } else { + return getQueryExecution(getQueryMethod(), extractor, rowMapper); + } + } + } + protected ParametrizedQuery createQuery(RelationalParametersParameterAccessor accessor, ReturnedType returnedType) { RelationalEntityMetadata entityMetadata = getQueryMethod().getEntityInformation(); diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/Query.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/Query.java index b121d3569d..a772e5746d 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/Query.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/Query.java @@ -29,6 +29,18 @@ * Annotation to provide SQL statements that will get used for executing the method. The SQL statement may contain named * parameters as supported by {@link org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate}. Those * parameters will get bound to the arguments of the annotated method. + *

+ * You can also specify the way to extract data from {@link java.sql.ResultSet}. There are 4 attribute of this + * annotation you can set to do that: + *

+ * 1. {@link #resultSetExtractorRef()} + * 2. {@link #resultSetExtractorClass()} + * 3. {@link #rowMapperRef()} + * 4. {@link #rowMapperClass()} + * + * The annotation attributes above are listed in their preference order, that is - the {@link #resultSetExtractorRef()}, + * has the highest privilege and, will suppress any other 3 attribute from above, and consequently {@link #rowMapperClass()} + * has the lowest privilege and will be used if any of three above are not specified. * * @author Jens Schauder * @author Moises Cisneros @@ -52,28 +64,23 @@ String name() default ""; /** - * Optional {@link RowMapper} to use to convert the result of the query to domain class instances. Cannot be used - * along with {@link #resultSetExtractorClass()} only one of the two can be set. + * Optional {@link RowMapper} to use to convert the result of the query to domain class instances. */ Class rowMapperClass() default RowMapper.class; /** - * Optional name of a bean of type {@link RowMapper} to use to convert the result of the query to domain class instances. Cannot be used - * along with {@link #resultSetExtractorClass()} only one of the two can be set. - * + * Optional name of a bean of type {@link RowMapper} to use to convert the result of the query to domain class instances. * @since 2.1 */ String rowMapperRef() default ""; /** - * Optional {@link ResultSetExtractor} to use to convert the result of the query to domain class instances. Cannot be - * used along with {@link #rowMapperClass()} only one of the two can be set. + * Optional {@link ResultSetExtractor} to use to convert the result of the query to domain class instances. */ Class resultSetExtractorClass() default ResultSetExtractor.class; /** - * Optional name of a bean of type {@link ResultSetExtractor} to use to convert the result of the query to domain class instances. Cannot be - * used along with {@link #rowMapperClass()} only one of the two can be set. + * Optional name of a bean of type {@link ResultSetExtractor} to use to convert the result of the query to domain class instances. * * @since 2.1 */ diff --git a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/StringBasedJdbcQuery.java b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/StringBasedJdbcQuery.java index 87d18b5775..690cad0653 100644 --- a/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/StringBasedJdbcQuery.java +++ b/spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/StringBasedJdbcQuery.java @@ -128,13 +128,7 @@ public Object execute(Object[] objects) { ResultProcessingConverter converter = new ResultProcessingConverter(processor, this.converter.getMappingContext(), this.converter.getEntityInstantiators()); - RowMapper rowMapper = determineRowMapper(rowMapperFactory.create(resolveTypeToRead(processor)), converter, - accessor.findDynamicProjection() != null); - - JdbcQueryExecution queryExecution = getQueryExecution(// - queryMethod, // - determineResultSetExtractor(rowMapper), // - rowMapper); + JdbcQueryExecution queryExecution = createJdbcQueryExecution(accessor, processor, converter); MapSqlParameterSource parameterMap = this.bindParameters(accessor); @@ -147,6 +141,21 @@ public Object execute(Object[] objects) { return queryExecution.execute(processSpelExpressions(objects, parameterMap, query), parameterMap); } + private JdbcQueryExecution createJdbcQueryExecution(RelationalParameterAccessor accessor, ResultProcessor processor, ResultProcessingConverter converter) { + JdbcQueryExecution queryExecution; + + if (queryMethod.isModifyingQuery()) { + queryExecution = createModifyingQueryExecutor(); + } else { + + RowMapper rowMapper = determineRowMapper(rowMapperFactory.create(resolveTypeToRead(processor)), converter, + accessor.findDynamicProjection() != null); + + queryExecution = getQueryExecution(queryMethod, determineResultSetExtractor(rowMapper), rowMapper); + } + return queryExecution; + } + private String processSpelExpressions(Object[] objects, MapSqlParameterSource parameterMap, String query) { SpelQueryContext.EvaluatingSpelQueryContext queryContext = SpelQueryContext