Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
* @author Tyler Van Gorder
* @author Milan Milanov
* @author Myeonghyeon Lee
* @author Christopher Klein
*/
public class MyBatisDataAccessStrategy implements DataAccessStrategy {

Expand Down Expand Up @@ -319,12 +320,17 @@ public <T> Iterable<T> findAllById(Iterable<?> ids, Class<T> domainType) {
public Iterable<Object> findAllByPath(Identifier identifier,
PersistentPropertyPath<? extends RelationalPersistentProperty> path) {

String statementName = namespace(path.getBaseProperty().getOwner().getType()) + ".findAllByPath-"


// Using "path.getBaseProperty().getOwner().getType()" will throw "The method getOwner() is ambiguous for the type capture#12-of ? extends RelationalPersistentProperty" in Eclipse
RelationalPersistentProperty prop = path.getBaseProperty();
Class<?> clazz = prop.getOwner().getType();

String statementName = namespace(clazz) + ".findAllByPath-"
+ path.toDotPath();

return sqlSession().selectList(statementName,
new MyBatisContext(identifier, null, path.getRequiredLeafProperty().getType()));

}

/*
Expand Down
105 changes: 81 additions & 24 deletions ...bc/src/main/java/org/springframework/data/jdbc/repository/query/StringBasedJdbcQuery.java
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,24 @@

import java.lang.reflect.Constructor;
import java.sql.JDBCType;
import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.BeanUtils;
import org.springframework.data.jdbc.core.convert.JdbcColumnTypes;
import org.springframework.data.jdbc.core.convert.JdbcConverter;
import org.springframework.data.jdbc.core.convert.JdbcValue;
import org.springframework.data.jdbc.repository.query.parameter.ParameterBindingParser;
import org.springframework.data.jdbc.repository.query.parameter.ParameterBindings.Metadata;
import org.springframework.data.jdbc.repository.query.parameter.ParameterBindings.ParameterBinding;
import org.springframework.data.jdbc.support.JdbcUtil;
import org.springframework.data.relational.core.mapping.RelationalMappingContext;
import org.springframework.data.repository.query.Parameter;
import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.jdbc.core.ResultSetExtractor;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
Expand All @@ -34,14 +44,15 @@
import org.springframework.util.StringUtils;

/**
* A query to be executed based on a repository method, it's annotated SQL query and the arguments provided to the
* method.
* A query to be executed based on a repository method, it's annotated SQL query
* and the arguments provided to the method.
*
* @author Jens Schauder
* @author Kazuki Shimizu
* @author Oliver Gierke
* @author Maciej Walkowiak
* @author Mark Paluch
* @author Christopher Klein
* @since 2.0
*/
public class StringBasedJdbcQuery extends AbstractJdbcQuery {
Expand All @@ -51,22 +62,27 @@ public class StringBasedJdbcQuery extends AbstractJdbcQuery {
private final JdbcQueryMethod queryMethod;
private final JdbcQueryExecution<?> executor;
private final JdbcConverter converter;
private final QueryMethodEvaluationContextProvider evaluationContextProvider;

/**
* Creates a new {@link StringBasedJdbcQuery} for the given {@link JdbcQueryMethod}, {@link RelationalMappingContext}
* and {@link RowMapper}.
* Creates a new {@link StringBasedJdbcQuery} for the given
* {@link JdbcQueryMethod}, {@link RelationalMappingContext} and
* {@link RowMapper}.
*
* @param queryMethod must not be {@literal null}.
* @param operations must not be {@literal null}.
* @param defaultRowMapper can be {@literal null} (only in case of a modifying query).
* @param queryMethod must not be {@literal null}.
* @param operations must not be {@literal null}.
* @param defaultRowMapper can be {@literal null} (only in case of a modifying
* query).
*/
public StringBasedJdbcQuery(JdbcQueryMethod queryMethod, NamedParameterJdbcOperations operations,
@Nullable RowMapper<?> defaultRowMapper, JdbcConverter converter) {
@Nullable RowMapper<?> defaultRowMapper, JdbcConverter converter,
QueryMethodEvaluationContextProvider evaluationContextProvider) {

super(queryMethod, operations, defaultRowMapper);

this.queryMethod = queryMethod;
this.converter = converter;
this.evaluationContextProvider = evaluationContextProvider;

RowMapper<Object> rowMapper = determineRowMapper(defaultRowMapper);
executor = getQueryExecution( //
Expand All @@ -78,24 +94,76 @@ public StringBasedJdbcQuery(JdbcQueryMethod queryMethod, NamedParameterJdbcOpera

/*
* (non-Javadoc)
* @see org.springframework.data.repository.query.RepositoryQuery#execute(java.lang.Object[])
*
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please do not reformat parts of the code that shall remain untouched. You can find our formatter settings for Eclipse (IntelliJ IDEA via Eclipse Formatter Plugin) at https://github.com/spring-projects/spring-data-build/tree/master/etc/ide.

* @see
* org.springframework.data.repository.query.RepositoryQuery#execute(java.lang.
* Object[])
*/
@Override
public Object execute(Object[] objects) {
return executor.execute(determineQuery(), this.bindParameters(objects));

Metadata queryMeta = new Metadata();

String query = queryMethod.getDeclaredQuery();

if (StringUtils.isEmpty(query)) {
throw new IllegalStateException(String.format("No query specified on %s", queryMethod.getName()));
}

List<ParameterBinding> bindings = new ArrayList<>();

query = ParameterBindingParser.INSTANCE.parseParameterBindingsOfQueryIntoBindingsAndReturnCleanedQuery(query,
bindings, queryMeta);

MapSqlParameterSource parameterMap = this.bindMethodParameters(objects);

extendParametersFromSpELEvaluation(parameterMap, bindings, objects);
return executor.execute(query, parameterMap);
}

/**
* Extend the {@link MapSqlParameterSource} by evaluating each detected SpEL
* parameter in the original query.
*
* This is basically a simple variant of Spring Data JPA's SPeL implementation.
*
* @param parameterMap
* @param bindings
* @param values
*/
void extendParametersFromSpELEvaluation(MapSqlParameterSource parameterMap, List<ParameterBinding> bindings, Object[] values) {

if (bindings.size() == 0) {
return;
}

ExpressionParser parser = new SpelExpressionParser();

bindings.forEach(binding -> {
if (!binding.isExpression()) {
return;
}

Expression expression = parser.parseExpression(binding.getExpression());
EvaluationContext context = evaluationContextProvider.getEvaluationContext(this.queryMethod.getParameters(),
values);

parameterMap.addValue(binding.getName(), expression.getValue(context, Object.class));
});
}

/*
* (non-Javadoc)
* @see org.springframework.data.repository.query.RepositoryQuery#getQueryMethod()
*
* @see
* org.springframework.data.repository.query.RepositoryQuery#getQueryMethod()
*/
@Override
public JdbcQueryMethod getQueryMethod() {
return queryMethod;
}

MapSqlParameterSource bindParameters(Object[] objects) {

MapSqlParameterSource bindMethodParameters(Object[] objects) {
MapSqlParameterSource parameters = new MapSqlParameterSource();

queryMethod.getParameters().getBindableParameters()
Expand Down Expand Up @@ -123,17 +191,6 @@ private void convertAndAddParameter(MapSqlParameterSource parameters, Parameter
}
}

private String determineQuery() {

String query = queryMethod.getDeclaredQuery();

if (StringUtils.isEmpty(query)) {
throw new IllegalStateException(String.format("No query specified on %s", queryMethod.getName()));
}

return query;
}

@Nullable
@SuppressWarnings({ "rawtypes", "unchecked" })
ResultSetExtractor<Object> determineResultSetExtractor(@Nullable RowMapper<Object> rowMapper) {
Expand Down
Loading