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
This commit is contained in:
@@ -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 {
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
if (queryMethod.isCollectionQuery()) {
|
||||
return extractor != null ? getQueryExecution(extractor) : collectionQuery(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 (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 {
|
||||
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 {
|
||||
}
|
||||
|
||||
<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 {
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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,18 +173,6 @@ public class PartTreeJdbcQuery extends AbstractJdbcQuery {
|
||||
return queryExecution;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected ParametrizedQuery createQuery(RelationalParametersParameterAccessor accessor, ReturnedType returnedType) {
|
||||
|
||||
RelationalEntityMetadata<?> entityMetadata = getQueryMethod().getEntityInformation();
|
||||
@@ -193,6 +182,20 @@ public class PartTreeJdbcQuery extends AbstractJdbcQuery {
|
||||
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 createReadingQueryExecution(extractor, rowMapper);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link JdbcQueryExecution} returning a {@link org.springframework.data.domain.Slice}.
|
||||
*
|
||||
|
||||
@@ -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;
|
||||
* @author Jens Schauder
|
||||
* @author Moises Cisneros
|
||||
* @author Hebert Coelho
|
||||
* @author Mikhail Polivakha
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
|
||||
@@ -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 {
|
||||
|
||||
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 {
|
||||
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 {
|
||||
.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 {
|
||||
|
||||
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 {
|
||||
|
||||
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 {
|
||||
@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 {
|
||||
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 {
|
||||
@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 {
|
||||
return (RowMapper<Object>) beanFactory.getBean(rowMapperRef);
|
||||
}
|
||||
|
||||
Class<?> rowMapperClass = queryMethod.getRowMapperClass();
|
||||
Class<?> rowMapperClass = getQueryMethod().getRowMapperClass();
|
||||
|
||||
if (isUnconfigured(rowMapperClass, RowMapper.class)) {
|
||||
return (RowMapper<Object>) defaultMapper;
|
||||
|
||||
Reference in New Issue
Block a user