Skip to content

Commit

Permalink
support slice/page query in StringBasedJdbcQuery
Browse files Browse the repository at this point in the history
  • Loading branch information
guodage committed Apr 3, 2024
1 parent 51cd894 commit 32b231f
Showing 1 changed file with 36 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jdbc.core.convert.JdbcColumnTypes;
import org.springframework.data.jdbc.core.convert.JdbcConverter;
import org.springframework.data.jdbc.core.mapping.JdbcValue;
Expand Down Expand Up @@ -109,16 +110,6 @@ public StringBasedJdbcQuery(JdbcQueryMethod queryMethod, NamedParameterJdbcOpera
this.converter = converter;
this.rowMapperFactory = rowMapperFactory;
this.evaluationContextProvider = evaluationContextProvider;

if (queryMethod.isSliceQuery()) {
throw new UnsupportedOperationException(
"Slice queries are not supported using string-based queries; Offending method: " + queryMethod);
}

if (queryMethod.isPageQuery()) {
throw new UnsupportedOperationException(
"Page queries are not supported using string-based queries; Offending method: " + queryMethod);
}
}

@Override
Expand All @@ -132,10 +123,9 @@ public Object execute(Object[] objects) {
RowMapper<Object> rowMapper = determineRowMapper(rowMapperFactory.create(resolveTypeToRead(processor)), converter,
accessor.findDynamicProjection() != null);

JdbcQueryExecution<?> queryExecution = getQueryExecution(//
queryMethod, //
determineResultSetExtractor(rowMapper), //
rowMapper);
JdbcQueryExecution<?> queryExecution = queryMethod.isPageQuery() || queryMethod.isSliceQuery()
? collectionQuery(rowMapper)
: getQueryExecution(queryMethod, determineResultSetExtractor(rowMapper), rowMapper);

MapSqlParameterSource parameterMap = this.bindParameters(accessor);

Expand All @@ -145,9 +135,33 @@ public Object execute(Object[] objects) {
throw new IllegalStateException(String.format("No query specified on %s", queryMethod.getName()));
}

if (queryMethod.isSliceQuery() || queryMethod.isPageQuery()) {
queryExecution = wrapPageableQueryExecution(accessor, parameterMap, queryExecution);
}

return queryExecution.execute(processSpelExpressions(objects, parameterMap, query), parameterMap);
}

private JdbcQueryExecution<?> wrapPageableQueryExecution(RelationalParameterAccessor accessor, MapSqlParameterSource parameterMap, JdbcQueryExecution<?> queryExecution) {
Pageable pageable = accessor.getPageable();
parameterMap.addValue("offset", pageable.getOffset());
if (queryMethod.isSliceQuery()) {
parameterMap.addValue("limit", pageable.getPageSize() + 1);
queryExecution = new PartTreeJdbcQuery.SliceQueryExecution<>((JdbcQueryExecution<Collection<Object>>) queryExecution, pageable);
}else if (queryMethod.isPageQuery()) {
parameterMap.addValue("limit", pageable.getPageSize());
queryExecution = new PartTreeJdbcQuery.PageQueryExecution<>((JdbcQueryExecution<Collection<Object>>) queryExecution, pageable,
() -> {
String querySql = getQueryMethod().getDeclaredQuery();
String countQuerySql = querySql.replaceFirst("(?i)select .*? from", "select count(*) from")
.replaceFirst("(?i) order by .*", "");
Object count = singleObjectQuery((rs, i) -> rs.getLong(1)).execute(countQuerySql, parameterMap);
return this.converter.getConversionService().convert(count, Long.class);
});
}
return queryExecution;
}

private String processSpelExpressions(Object[] objects, MapSqlParameterSource parameterMap, String query) {

SpelQueryContext.EvaluatingSpelQueryContext queryContext = SpelQueryContext
Expand Down Expand Up @@ -225,10 +239,17 @@ private String determineQuery() {
if (ObjectUtils.isEmpty(query)) {
throw new IllegalStateException(String.format("No query specified on %s", queryMethod.getName()));
}

if (queryMethod.isPageQuery() || queryMethod.isSliceQuery()) {
return enhancePageQuery(query);
}
return query;
}

private String enhancePageQuery(String query) {
String original = query.trim().replace(";", "");
return String.format("%s limit :limit offset :offset", original);
}

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

0 comments on commit 32b231f

Please # to comment.