DATAJDBC-101 - Polishing.

Refactored SQL generation.
Adapted some assertions to the "Spring Data JDBC style".
Minor formatting.

Original pull request: #188.
This commit is contained in:
Jens Schauder
2020-02-07 09:59:49 +01:00
parent 7f578ed2bb
commit 4a8888e296
6 changed files with 45 additions and 36 deletions

View File

@@ -140,6 +140,7 @@ public interface JdbcAggregateOperations {
* @param <T> the type of the aggregate roots. Must not be {@code null}.
* @param sort the sorting information. Must not be {@code null}.
* @return Guaranteed to be not {@code null}.
* @since 2.0
*/
<T> Iterable<T> findAll(Class<T> domainType, Sort sort);
@@ -150,6 +151,7 @@ public interface JdbcAggregateOperations {
* @param <T> the type of the aggregate roots. Must not be {@code null}.
* @param pageable the pagination information. Must not be {@code null}.
* @return Guaranteed to be not {@code null}.
* @since 2.0
*/
<T> Page<T> findAll(Class<T> domainType, Pageable pageable);
}

View File

@@ -226,6 +226,7 @@ public interface DataAccessStrategy extends RelationResolver {
* @param <T> the type of entities to load.
* @param sort the sorting information. Must not be {@code null}.
* @return Guaranteed to be not {@code null}.
* @since 2.0
*/
<T> Iterable<T> findAll(Class<T> domainType, Sort sort);
@@ -236,6 +237,7 @@ public interface DataAccessStrategy extends RelationResolver {
* @param <T> the type of entities to load.
* @param pageable the pagination information. Must not be {@code null}.
* @return Guaranteed to be not {@code null}.
* @since 2.0
*/
<T> Iterable<T> findAll(Class<T> domainType, Pageable pageable);
}

View File

@@ -17,16 +17,7 @@ package org.springframework.data.jdbc.core.convert;
import lombok.Value;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.*;
import java.util.function.Function;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
@@ -420,24 +411,29 @@ class SqlGenerator {
}
private SelectBuilder.SelectOrdered selectBuilder(Collection<String> keyColumns, Sort sort, Pageable pageable) {
SelectBuilder.SelectWhere baseSelect = this.selectBuilder(keyColumns);
if (baseSelect instanceof SelectBuilder.SelectFromAndJoin) {
if (pageable.isPaged()) {
return ((SelectBuilder.SelectFromAndJoin) baseSelect).limitOffset(pageable.getPageSize(), pageable.getOffset())
.orderBy(extractOrderByFields(sort));
}
return ((SelectBuilder.SelectFromAndJoin) baseSelect).orderBy(extractOrderByFields(sort));
SelectBuilder.SelectOrdered sortable = this.selectBuilder(keyColumns);
sortable = applyPagination(pageable, sortable);
return sortable.orderBy(extractOrderByFields(sort));
} else if (baseSelect instanceof SelectBuilder.SelectFromAndJoinCondition) {
if (pageable.isPaged()) {
return ((SelectBuilder.SelectFromAndJoinCondition) baseSelect)
.limitOffset(pageable.getPageSize(), pageable.getOffset()).orderBy(extractOrderByFields(sort));
}
return baseSelect.orderBy(extractOrderByFields(sort));
} else {
throw new RuntimeException("Unexpected type found!");
}
private SelectBuilder.SelectOrdered applyPagination(Pageable pageable, SelectBuilder.SelectOrdered select) {
if (!pageable.isPaged()) {
return select;
}
Assert.isTrue(select instanceof SelectBuilder.SelectLimitOffset,
() -> String.format("Can't apply limit clause to statement of type %s", select.getClass()));
SelectBuilder.SelectLimitOffset limitable = (SelectBuilder.SelectLimitOffset) select;
SelectBuilder.SelectLimitOffset limitResult = limitable.limitOffset(pageable.getPageSize(), pageable.getOffset());
Assert.state(limitResult instanceof SelectBuilder.SelectOrdered,
String.format("The result of applying the limit-clause must be of type SelectOrdered in order to apply the order-by-clause but is of type %s.", select.getClass()));
return (SelectBuilder.SelectOrdered) limitResult;
}
/**

View File

@@ -347,6 +347,7 @@ public class MyBatisDataAccessStrategy implements DataAccessStrategy {
*/
@Override
public <T> Iterable<T> findAll(Class<T> domainType, Sort sort) {
Map<String, Object> additionalContext = new HashMap<>();
additionalContext.put("sort", sort);
return sqlSession().selectList(namespace(domainType) + ".findAllSorted",
@@ -359,6 +360,7 @@ public class MyBatisDataAccessStrategy implements DataAccessStrategy {
*/
@Override
public <T> Iterable<T> findAll(Class<T> domainType, Pageable pageable) {
Map<String, Object> additionalContext = new HashMap<>();
additionalContext.put("pageable", pageable);
return sqlSession().selectList(namespace(domainType) + ".findAllPaged",

View File

@@ -40,7 +40,7 @@ import org.springframework.transaction.annotation.Transactional;
*/
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class SimpleJdbcRepository<T, ID> implements CrudRepository<T, ID>, PagingAndSortingRepository<T, ID> {
public class SimpleJdbcRepository<T, ID> implements PagingAndSortingRepository<T, ID> {
private final @NonNull JdbcAggregateOperations entityOperations;
private final @NonNull PersistentEntity<T, ?> entity;

View File

@@ -39,7 +39,6 @@ import org.junit.Assume;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.annotation.Bean;
@@ -225,41 +224,51 @@ public class JdbcAggregateTemplateIntegrationTests {
Iterable<LegoSet> reloadedLegoSets = template.findAll(LegoSet.class);
assertThat(reloadedLegoSets).hasSize(1).extracting("id", "manual.id", "manual.content")
.contains(tuple(legoSet.getId(), legoSet.getManual().getId(), legoSet.getManual().getContent()));
assertThat(reloadedLegoSets) //
.extracting("id", "manual.id", "manual.content") //
.containsExactly(tuple(legoSet.getId(), legoSet.getManual().getId(), legoSet.getManual().getContent()));
}
@Test // DATAJDBC-101
public void saveAndLoadManyEntitiesWithReferencedEntitySorted() {
template.save(createLegoSet("Lava"));
template.save(createLegoSet("Star"));
template.save(createLegoSet("Frozen"));
Iterable<LegoSet> reloadedLegoSets = template.findAll(LegoSet.class, Sort.by("name"));
assertThat(reloadedLegoSets).hasSize(3).extracting("name").isEqualTo(Arrays.asList("Frozen", "Lava", "Star"));
assertThat(reloadedLegoSets) //
.extracting("name") //
.containsExactly("Frozen", "Lava", "Star");
}
@Test // DATAJDBC-101
public void saveAndLoadManyEntitiesWithReferencedEntityPaged() {
template.save(createLegoSet("Lava"));
template.save(createLegoSet("Star"));
template.save(createLegoSet("Frozen"));
Iterable<LegoSet> reloadedLegoSets = template.findAll(LegoSet.class, PageRequest.of(1, 1));
assertThat(reloadedLegoSets).hasSize(1).extracting("name").isEqualTo(singletonList("Star"));
assertThat(reloadedLegoSets) //
.extracting("name") //
.containsExactly("Star");
}
@Test // DATAJDBC-101
public void saveAndLoadManyEntitiesWithReferencedEntitySortedAndPaged() {
template.save(createLegoSet("Lava"));
template.save(createLegoSet("Star"));
template.save(createLegoSet("Frozen"));
Iterable<LegoSet> reloadedLegoSets = template.findAll(LegoSet.class, PageRequest.of(1, 2, Sort.by("name")));
assertThat(reloadedLegoSets).hasSize(1).extracting("name").isEqualTo(singletonList("Star"));
assertThat(reloadedLegoSets) //
.extracting("name") //
.containsExactly("Star");
}
@Test // DATAJDBC-112
@@ -749,12 +758,10 @@ public class JdbcAggregateTemplateIntegrationTests {
AggregateWithImmutableVersion savedAgain = template.save(reloadedAggregate);
AggregateWithImmutableVersion reloadedAgain = template.findById(id, aggregate.getClass());
assertThat(savedAgain.version)
.describedAs("The object returned by save should have an increased version")
assertThat(savedAgain.version).describedAs("The object returned by save should have an increased version")
.isEqualTo(2L);
assertThat(reloadedAgain.getVersion())
.describedAs("version field should increment by one with each save")
assertThat(reloadedAgain.getVersion()).describedAs("version field should increment by one with each save")
.isEqualTo(2L);
assertThatThrownBy(() -> template.save(new AggregateWithImmutableVersion(id, 1L)))