Browse Source

Polishing.

Simplified use of queryMethod in the different JdbcQuery classes.
Improved method names.
Added author tags.
Code formatting.
Corrected HTML in JavaDoc.

Originial pull request #1423
pull/1356/head
Jens Schauder 3 years ago
parent
commit
0b85b6f216
No known key found for this signature in database
GPG Key ID: 9537B67540F0A581
  1. 41
      spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/AbstractJdbcQuery.java
  2. 23
      spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/PartTreeJdbcQuery.java
  3. 12
      spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/Query.java
  4. 38
      spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/StringBasedJdbcQuery.java

41
spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/AbstractJdbcQuery.java

@ -42,6 +42,7 @@ import org.springframework.util.Assert; @@ -42,6 +42,7 @@ import org.springframework.util.Assert;
* @author Maciej Walkowiak
* @author Mark Paluch
* @author Dennis Effing
* @author Mikhail Polivakha
* @since 2.0
*/
public abstract class AbstractJdbcQuery implements RepositoryQuery {
@ -71,26 +72,42 @@ public abstract class AbstractJdbcQuery implements RepositoryQuery { @@ -71,26 +72,42 @@ public abstract class AbstractJdbcQuery implements RepositoryQuery {
}
/**
* Creates a {@link JdbcQueryExecution} given {@link JdbcQueryMethod}, {@link ResultSetExtractor} an
* Creates a {@link JdbcQueryExecution} given a {@link JdbcQueryMethod}, and ac{@link ResultSetExtractor} or a
* {@link RowMapper}. Prefers the given {@link ResultSetExtractor} over {@link RowMapper}.
*
* @param queryMethod must not be {@literal null}.
* @param extractor must not be {@literal null}.
* @param rowMapper must not be {@literal null}.
* @return a JdbcQueryExecution appropriate for {@literal queryMethod}. Guaranteed to be not {@literal null}.
* @deprecated use {@link #createReadingQueryExecution(ResultSetExtractor, RowMapper)} instead.
*/
@Deprecated(since = "3.1", forRemoval = true)
// a better name would be createReadingQueryExecution
protected JdbcQueryExecution<?> getQueryExecution(JdbcQueryMethod queryMethod,
@Nullable ResultSetExtractor<?> extractor, RowMapper<?> rowMapper) {
return createReadingQueryExecution(extractor, rowMapper);
}
/**
* Creates a {@link JdbcQueryExecution} given a {@link ResultSetExtractor} or a {@link RowMapper}. Prefers the given
* {@link ResultSetExtractor} over {@link RowMapper}.
*
* @param extractor must not be {@literal null}.
* @param rowMapper must not be {@literal null}.
* @return a JdbcQueryExecution appropriate for {@literal queryMethod}. Guaranteed to be not {@literal null}.
*/
protected JdbcQueryExecution<?> createReadingQueryExecution(@Nullable ResultSetExtractor<?> extractor,
RowMapper<?> rowMapper) {
if (queryMethod.isCollectionQuery()) {
return extractor != null ? getQueryExecution(extractor) : collectionQuery(rowMapper);
if (getQueryMethod().isCollectionQuery()) {
return extractor != null ? createSingleReadingQueryExecution(extractor) : collectionQuery(rowMapper);
}
if (queryMethod.isStreamQuery()) {
return extractor != null ? getQueryExecution(extractor) : streamQuery(rowMapper);
if (getQueryMethod().isStreamQuery()) {
return extractor != null ? createSingleReadingQueryExecution(extractor) : streamQuery(rowMapper);
}
return extractor != null ? getQueryExecution(extractor) : singleObjectQuery(rowMapper);
return extractor != null ? createSingleReadingQueryExecution(extractor) : singleObjectQuery(rowMapper);
}
protected JdbcQueryExecution<Object> createModifyingQueryExecutor() {
@ -100,7 +117,8 @@ public abstract class AbstractJdbcQuery implements RepositoryQuery { @@ -100,7 +117,8 @@ public abstract class AbstractJdbcQuery implements RepositoryQuery {
int updatedCount = operations.update(query, parameters);
Class<?> returnedObjectType = queryMethod.getReturnedObjectType();
return (returnedObjectType == boolean.class || returnedObjectType == Boolean.class) ? updatedCount != 0
return (returnedObjectType == boolean.class || returnedObjectType == Boolean.class) //
? updatedCount != 0 //
: updatedCount;
};
}
@ -117,14 +135,15 @@ public abstract class AbstractJdbcQuery implements RepositoryQuery { @@ -117,14 +135,15 @@ public abstract class AbstractJdbcQuery implements RepositoryQuery {
}
<T> JdbcQueryExecution<List<T>> collectionQuery(RowMapper<T> rowMapper) {
return getQueryExecution(new RowMapperResultSetExtractor<>(rowMapper));
return createSingleReadingQueryExecution(new RowMapperResultSetExtractor<>(rowMapper));
}
/**
* Obtain the result type to read from {@link ResultProcessor}.
*
* @param resultProcessor the {@link ResultProcessor} used to determine the result type. Must not be {@literal null}.
* @return the type that should get loaded from the database before it gets converted into the actual return type of a method. Guaranteed to be not {@literal null}.
* @param resultProcessor the {@link ResultProcessor} used to determine the result type. Must not be {@literal null}.
* @return the type that should get loaded from the database before it gets converted into the actual return type of a
* method. Guaranteed to be not {@literal null}.
*/
protected Class<?> resolveTypeToRead(ResultProcessor resultProcessor) {
@ -142,7 +161,7 @@ public abstract class AbstractJdbcQuery implements RepositoryQuery { @@ -142,7 +161,7 @@ public abstract class AbstractJdbcQuery implements RepositoryQuery {
return (query, parameters) -> operations.queryForStream(query, parameters, rowMapper);
}
private <T> JdbcQueryExecution<T> getQueryExecution(ResultSetExtractor<T> resultSetExtractor) {
private <T> JdbcQueryExecution<T> createSingleReadingQueryExecution(ResultSetExtractor<T> resultSetExtractor) {
return (query, parameters) -> operations.query(query, parameters, resultSetExtractor);
}

23
spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/PartTreeJdbcQuery.java

@ -52,6 +52,7 @@ import org.springframework.util.Assert; @@ -52,6 +52,7 @@ import org.springframework.util.Assert;
* @author Mark Paluch
* @author Jens Schauder
* @author Diego Krupitza
* @author Mikhail Polivakha
* @since 2.0
*/
public class PartTreeJdbcQuery extends AbstractJdbcQuery {
@ -172,27 +173,29 @@ public class PartTreeJdbcQuery extends AbstractJdbcQuery { @@ -172,27 +173,29 @@ public class PartTreeJdbcQuery extends AbstractJdbcQuery {
return queryExecution;
}
protected ParametrizedQuery createQuery(RelationalParametersParameterAccessor accessor, ReturnedType returnedType) {
RelationalEntityMetadata<?> entityMetadata = getQueryMethod().getEntityInformation();
JdbcQueryCreator queryCreator = new JdbcQueryCreator(context, tree, converter, dialect, entityMetadata, accessor,
getQueryMethod().isSliceQuery(), returnedType, this.getQueryMethod().lookupLockAnnotation());
return queryCreator.createQuery(getDynamicSort(accessor));
}
private JdbcQueryExecution<?> getJdbcQueryExecution(@Nullable ResultSetExtractor<Boolean> extractor, RowMapper<Object> rowMapper) {
if (getQueryMethod().isPageQuery() || getQueryMethod().isSliceQuery()) {
return collectionQuery(rowMapper);
} else {
if (getQueryMethod().isModifyingQuery()) {
return createModifyingQueryExecutor();
} else {
return getQueryExecution(getQueryMethod(), extractor, rowMapper);
return createReadingQueryExecution(extractor, rowMapper);
}
}
}
protected ParametrizedQuery createQuery(RelationalParametersParameterAccessor accessor, ReturnedType returnedType) {
RelationalEntityMetadata<?> entityMetadata = getQueryMethod().getEntityInformation();
JdbcQueryCreator queryCreator = new JdbcQueryCreator(context, tree, converter, dialect, entityMetadata, accessor,
getQueryMethod().isSliceQuery(), returnedType, this.getQueryMethod().lookupLockAnnotation());
return queryCreator.createQuery(getDynamicSort(accessor));
}
/**
* {@link JdbcQueryExecution} returning a {@link org.springframework.data.domain.Slice}.
*

12
spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/Query.java

@ -33,10 +33,13 @@ import org.springframework.jdbc.core.RowMapper; @@ -33,10 +33,13 @@ import org.springframework.jdbc.core.RowMapper;
* 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:
* <p>
* 1. {@link #resultSetExtractorRef()}
* 2. {@link #resultSetExtractorClass()}
* 3. {@link #rowMapperRef()}
* 4. {@link #rowMapperClass()}
* <ol>
* <li> {@link #resultSetExtractorRef()}
* </li><li> {@link #resultSetExtractorClass()}
* </li><li> {@link #rowMapperRef()}
* </li><li> {@link #rowMapperClass()}
* </li>
*</ol>
*
* 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()}
@ -45,6 +48,7 @@ import org.springframework.jdbc.core.RowMapper; @@ -45,6 +48,7 @@ import org.springframework.jdbc.core.RowMapper;
* @author Jens Schauder
* @author Moises Cisneros
* @author Hebert Coelho
* @author Mikhail Polivakha
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)

38
spring-data-jdbc/src/main/java/org/springframework/data/jdbc/repository/query/StringBasedJdbcQuery.java

@ -61,13 +61,12 @@ import org.springframework.util.ObjectUtils; @@ -61,13 +61,12 @@ import org.springframework.util.ObjectUtils;
* @author Hebert Coelho
* @author Chirag Tailor
* @author Christopher Klein
* @author Mikhail Polivakha
* @since 2.0
*/
public class StringBasedJdbcQuery extends AbstractJdbcQuery {
private static final String PARAMETER_NEEDS_TO_BE_NAMED = "For queries with named parameters you need to provide names for method parameters; Use @Param for query method parameters, or when on Java 8+ use the javac flag -parameters";
private final JdbcQueryMethod queryMethod;
private final JdbcConverter converter;
private final RowMapperFactory rowMapperFactory;
private BeanFactory beanFactory;
@ -104,7 +103,6 @@ public class StringBasedJdbcQuery extends AbstractJdbcQuery { @@ -104,7 +103,6 @@ public class StringBasedJdbcQuery extends AbstractJdbcQuery {
Assert.notNull(rowMapperFactory, "RowMapperFactory must not be null");
this.queryMethod = queryMethod;
this.converter = converter;
this.rowMapperFactory = rowMapperFactory;
this.evaluationContextProvider = evaluationContextProvider;
@ -135,25 +133,24 @@ public class StringBasedJdbcQuery extends AbstractJdbcQuery { @@ -135,25 +133,24 @@ public class StringBasedJdbcQuery extends AbstractJdbcQuery {
String query = determineQuery();
if (ObjectUtils.isEmpty(query)) {
throw new IllegalStateException(String.format("No query specified on %s", queryMethod.getName()));
throw new IllegalStateException(String.format("No query specified on %s", getQueryMethod().getName()));
}
return queryExecution.execute(processSpelExpressions(objects, parameterMap, query), parameterMap);
}
private JdbcQueryExecution<?> createJdbcQueryExecution(RelationalParameterAccessor accessor, ResultProcessor processor, ResultProcessingConverter converter) {
JdbcQueryExecution<?> queryExecution;
private JdbcQueryExecution<?> createJdbcQueryExecution(RelationalParameterAccessor accessor,
ResultProcessor processor, ResultProcessingConverter converter) {
if (queryMethod.isModifyingQuery()) {
queryExecution = createModifyingQueryExecutor();
if (getQueryMethod().isModifyingQuery()) {
return createModifyingQueryExecutor();
} else {
RowMapper<Object> rowMapper = determineRowMapper(rowMapperFactory.create(resolveTypeToRead(processor)), converter,
accessor.findDynamicProjection() != null);
queryExecution = getQueryExecution(queryMethod, determineResultSetExtractor(rowMapper), rowMapper);
return createReadingQueryExecution(determineResultSetExtractor(rowMapper), rowMapper);
}
return queryExecution;
}
private String processSpelExpressions(Object[] objects, MapSqlParameterSource parameterMap, String query) {
@ -162,18 +159,13 @@ public class StringBasedJdbcQuery extends AbstractJdbcQuery { @@ -162,18 +159,13 @@ public class StringBasedJdbcQuery extends AbstractJdbcQuery {
.of((counter, expression) -> String.format("__$synthetic$__%d", counter + 1), String::concat)
.withEvaluationContextProvider(evaluationContextProvider);
SpelEvaluator spelEvaluator = queryContext.parse(query, queryMethod.getParameters());
SpelEvaluator spelEvaluator = queryContext.parse(query, getQueryMethod().getParameters());
spelEvaluator.evaluate(objects).forEach(parameterMap::addValue);
return spelEvaluator.getQueryString();
}
@Override
public JdbcQueryMethod getQueryMethod() {
return queryMethod;
}
private MapSqlParameterSource bindParameters(RelationalParameterAccessor accessor) {
MapSqlParameterSource parameters = new MapSqlParameterSource();
@ -191,7 +183,7 @@ public class StringBasedJdbcQuery extends AbstractJdbcQuery { @@ -191,7 +183,7 @@ public class StringBasedJdbcQuery extends AbstractJdbcQuery {
String parameterName = p.getName().orElseThrow(() -> new IllegalStateException(PARAMETER_NEEDS_TO_BE_NAMED));
RelationalParameters.RelationalParameter parameter = queryMethod.getParameters().getParameter(p.getIndex());
RelationalParameters.RelationalParameter parameter = getQueryMethod().getParameters().getParameter(p.getIndex());
ResolvableType resolvableType = parameter.getResolvableType();
Class<?> type = resolvableType.resolve();
Assert.notNull(type, "@Query parameter type could not be resolved");
@ -233,10 +225,10 @@ public class StringBasedJdbcQuery extends AbstractJdbcQuery { @@ -233,10 +225,10 @@ public class StringBasedJdbcQuery extends AbstractJdbcQuery {
private String determineQuery() {
String query = queryMethod.getDeclaredQuery();
String query = getQueryMethod().getDeclaredQuery();
if (ObjectUtils.isEmpty(query)) {
throw new IllegalStateException(String.format("No query specified on %s", queryMethod.getName()));
throw new IllegalStateException(String.format("No query specified on %s", getQueryMethod().getName()));
}
return query;
@ -246,7 +238,7 @@ public class StringBasedJdbcQuery extends AbstractJdbcQuery { @@ -246,7 +238,7 @@ public class StringBasedJdbcQuery extends AbstractJdbcQuery {
@SuppressWarnings({ "rawtypes", "unchecked" })
ResultSetExtractor<Object> determineResultSetExtractor(@Nullable RowMapper<Object> rowMapper) {
String resultSetExtractorRef = queryMethod.getResultSetExtractorRef();
String resultSetExtractorRef = getQueryMethod().getResultSetExtractorRef();
if (!ObjectUtils.isEmpty(resultSetExtractorRef)) {
@ -255,7 +247,7 @@ public class StringBasedJdbcQuery extends AbstractJdbcQuery { @@ -255,7 +247,7 @@ public class StringBasedJdbcQuery extends AbstractJdbcQuery {
return (ResultSetExtractor<Object>) beanFactory.getBean(resultSetExtractorRef);
}
Class<? extends ResultSetExtractor> resultSetExtractorClass = queryMethod.getResultSetExtractorClass();
Class<? extends ResultSetExtractor> resultSetExtractorClass = getQueryMethod().getResultSetExtractorClass();
if (isUnconfigured(resultSetExtractorClass, ResultSetExtractor.class)) {
return null;
@ -288,7 +280,7 @@ public class StringBasedJdbcQuery extends AbstractJdbcQuery { @@ -288,7 +280,7 @@ public class StringBasedJdbcQuery extends AbstractJdbcQuery {
@Nullable
RowMapper<Object> determineRowMapper(@Nullable RowMapper<?> defaultMapper) {
String rowMapperRef = queryMethod.getRowMapperRef();
String rowMapperRef = getQueryMethod().getRowMapperRef();
if (!ObjectUtils.isEmpty(rowMapperRef)) {
@ -297,7 +289,7 @@ public class StringBasedJdbcQuery extends AbstractJdbcQuery { @@ -297,7 +289,7 @@ public class StringBasedJdbcQuery extends AbstractJdbcQuery {
return (RowMapper<Object>) beanFactory.getBean(rowMapperRef);
}
Class<?> rowMapperClass = queryMethod.getRowMapperClass();
Class<?> rowMapperClass = getQueryMethod().getRowMapperClass();
if (isUnconfigured(rowMapperClass, RowMapper.class)) {
return (RowMapper<Object>) defaultMapper;

Loading…
Cancel
Save