DATAJDBC-137 - Cleanups in the repository and repository.support packages.
This commit is contained in:
@@ -100,7 +100,7 @@ public class CascadingDataAccessStrategy implements DataAccessStrategy {
|
||||
}
|
||||
|
||||
private <T> T collect(Function<DataAccessStrategy, T> function) {
|
||||
return strategies.stream().collect(new FunctionCollector<>(function));
|
||||
return strategies.stream().collect(new FunctionCollector<T>(function));
|
||||
}
|
||||
|
||||
private void collectVoid(Consumer<DataAccessStrategy> consumer) {
|
||||
|
||||
@@ -30,6 +30,10 @@ public interface RowMapperMap {
|
||||
*/
|
||||
RowMapperMap EMPTY = new RowMapperMap() {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.jdbc.repository.RowMapperMap#rowMapperFor(java.lang.Class)
|
||||
*/
|
||||
public <T> RowMapper<? extends T> rowMapperFor(Class<T> type) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -15,34 +15,27 @@
|
||||
*/
|
||||
package org.springframework.data.jdbc.repository;
|
||||
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.data.jdbc.core.JdbcEntityOperations;
|
||||
import org.springframework.data.jdbc.core.JdbcEntityTemplate;
|
||||
import org.springframework.data.jdbc.mapping.model.JdbcPersistentEntityInformation;
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
|
||||
/**
|
||||
* @author Jens Schauder
|
||||
* @author Oliver Gierke
|
||||
* @since 1.0
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
public class SimpleJdbcRepository<T, ID> implements CrudRepository<T, ID> {
|
||||
|
||||
private final JdbcPersistentEntityInformation<T, ID> entityInformation;
|
||||
|
||||
private final JdbcEntityOperations entityOperations;
|
||||
|
||||
/**
|
||||
* Creates a new {@link SimpleJdbcRepository}.
|
||||
*/
|
||||
public SimpleJdbcRepository(JdbcEntityTemplate entityOperations,
|
||||
JdbcPersistentEntityInformation<T, ID> entityInformation) {
|
||||
|
||||
this.entityOperations = entityOperations;
|
||||
this.entityInformation = entityInformation;
|
||||
}
|
||||
private final @NonNull JdbcEntityOperations entityOperations;
|
||||
private final @NonNull JdbcPersistentEntityInformation<T, ID> entityInformation;
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
@@ -136,12 +129,9 @@ public class SimpleJdbcRepository<T, ID> implements CrudRepository<T, ID> {
|
||||
* @see org.springframework.data.repository.CrudRepository#delete(java.lang.Iterable)
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void deleteAll(Iterable<? extends T> entities) {
|
||||
|
||||
for (T entity : entities) {
|
||||
entityOperations.delete(entity, (Class<T>) entity.getClass());
|
||||
|
||||
}
|
||||
entities.forEach(it -> entityOperations.delete(it, (Class<T>) it.getClass()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -26,16 +26,17 @@ import org.springframework.data.projection.ProjectionFactory;
|
||||
import org.springframework.data.repository.core.NamedQueries;
|
||||
import org.springframework.data.repository.core.RepositoryMetadata;
|
||||
import org.springframework.data.repository.query.QueryLookupStrategy;
|
||||
import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
|
||||
import org.springframework.data.repository.query.RepositoryQuery;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
import org.springframework.jdbc.core.SingleColumnRowMapper;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* {@link QueryLookupStrategy} for JDBC repositories. Currently only supports annotated queries.
|
||||
*
|
||||
* @author Jens Schauder
|
||||
* @author Kazuki Shimizu
|
||||
* @author Oliver Gierke
|
||||
* @since 1.0
|
||||
*/
|
||||
class JdbcQueryLookupStrategy implements QueryLookupStrategy {
|
||||
@@ -45,8 +46,19 @@ class JdbcQueryLookupStrategy implements QueryLookupStrategy {
|
||||
private final RowMapperMap rowMapperMap;
|
||||
private final ConversionService conversionService;
|
||||
|
||||
JdbcQueryLookupStrategy(QueryMethodEvaluationContextProvider evaluationContextProvider, JdbcMappingContext context,
|
||||
DataAccessStrategy accessStrategy, RowMapperMap rowMapperMap) {
|
||||
/**
|
||||
* Creates a new {@link JdbcQueryLookupStrategy} for the given {@link JdbcMappingContext}, {@link DataAccessStrategy}
|
||||
* and {@link RowMapperMap}.
|
||||
*
|
||||
* @param context must not be {@literal null}.
|
||||
* @param accessStrategy must not be {@literal null}.
|
||||
* @param rowMapperMap must not be {@literal null}.
|
||||
*/
|
||||
JdbcQueryLookupStrategy(JdbcMappingContext context, DataAccessStrategy accessStrategy, RowMapperMap rowMapperMap) {
|
||||
|
||||
Assert.notNull(context, "JdbcMappingContext must not be null!");
|
||||
Assert.notNull(accessStrategy, "DataAccessStrategy must not be null!");
|
||||
Assert.notNull(rowMapperMap, "RowMapperMap must not be null!");
|
||||
|
||||
this.context = context;
|
||||
this.accessStrategy = accessStrategy;
|
||||
@@ -54,6 +66,10 @@ class JdbcQueryLookupStrategy implements QueryLookupStrategy {
|
||||
this.conversionService = context.getConversions();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.query.QueryLookupStrategy#resolveQuery(java.lang.reflect.Method, org.springframework.data.repository.core.RepositoryMetadata, org.springframework.data.projection.ProjectionFactory, org.springframework.data.repository.core.NamedQueries)
|
||||
*/
|
||||
@Override
|
||||
public RepositoryQuery resolveQuery(Method method, RepositoryMetadata repositoryMetadata,
|
||||
ProjectionFactory projectionFactory, NamedQueries namedQueries) {
|
||||
@@ -78,7 +94,7 @@ class JdbcQueryLookupStrategy implements QueryLookupStrategy {
|
||||
|
||||
Class<?> domainType = queryMethod.getReturnedObjectType();
|
||||
|
||||
RowMapper typeMappedRowMapper = rowMapperMap.rowMapperFor(domainType);
|
||||
RowMapper<?> typeMappedRowMapper = rowMapperMap.rowMapperFor(domainType);
|
||||
|
||||
return typeMappedRowMapper == null //
|
||||
? new EntityRowMapper<>( //
|
||||
|
||||
@@ -45,38 +45,73 @@ public class JdbcRepositoryFactory extends RepositoryFactorySupport {
|
||||
private final JdbcMappingContext context;
|
||||
private final ApplicationEventPublisher publisher;
|
||||
private final DataAccessStrategy accessStrategy;
|
||||
|
||||
private RowMapperMap rowMapperMap = RowMapperMap.EMPTY;
|
||||
|
||||
public JdbcRepositoryFactory(ApplicationEventPublisher publisher, JdbcMappingContext context,
|
||||
DataAccessStrategy dataAccessStrategy) {
|
||||
/**
|
||||
* Creates a new {@link JdbcRepositoryFactory} for the given {@link DataAccessStrategy}, {@link JdbcMappingContext}
|
||||
* and {@link ApplicationEventPublisher}.
|
||||
*
|
||||
* @param dataAccessStrategy must not be {@literal null}.
|
||||
* @param context must not be {@literal null}.
|
||||
* @param publisher must not be {@literal null}.
|
||||
*/
|
||||
public JdbcRepositoryFactory(DataAccessStrategy dataAccessStrategy, JdbcMappingContext context,
|
||||
ApplicationEventPublisher publisher) {
|
||||
|
||||
Assert.notNull(dataAccessStrategy, "DataAccessStrategy must not be null!");
|
||||
Assert.notNull(context, "JdbcMappingContext must not be null!");
|
||||
Assert.notNull(publisher, "ApplicationEventPublisher must not be null!");
|
||||
|
||||
this.publisher = publisher;
|
||||
this.context = context;
|
||||
this.accessStrategy = dataAccessStrategy;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param rowMapperMap must not be {@literal null} consider {@link RowMapperMap#EMPTY} instead.
|
||||
*/
|
||||
public void setRowMapperMap(RowMapperMap rowMapperMap) {
|
||||
|
||||
Assert.notNull(rowMapperMap, "RowMapperMap must not be null!");
|
||||
|
||||
this.rowMapperMap = rowMapperMap;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <T, ID> EntityInformation<T, ID> getEntityInformation(Class<T> aClass) {
|
||||
return (EntityInformation<T, ID>) context.getRequiredPersistentEntityInformation(aClass);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.core.support.RepositoryFactorySupport#getTargetRepository(org.springframework.data.repository.core.RepositoryInformation)
|
||||
*/
|
||||
@Override
|
||||
protected Object getTargetRepository(RepositoryInformation repositoryInformation) {
|
||||
|
||||
JdbcPersistentEntityInformation persistentEntityInformation = context
|
||||
JdbcPersistentEntityInformation<?, ?> persistentEntityInformation = context
|
||||
.getRequiredPersistentEntityInformation(repositoryInformation.getDomainType());
|
||||
|
||||
JdbcEntityTemplate template = new JdbcEntityTemplate(publisher, context, accessStrategy);
|
||||
|
||||
return new SimpleJdbcRepository<>(template, persistentEntityInformation);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.core.support.RepositoryFactorySupport#getRepositoryBaseClass(org.springframework.data.repository.core.RepositoryMetadata)
|
||||
*/
|
||||
@Override
|
||||
protected Class<?> getRepositoryBaseClass(RepositoryMetadata repositoryMetadata) {
|
||||
return SimpleJdbcRepository.class;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.core.support.RepositoryFactorySupport#getQueryLookupStrategy(org.springframework.data.repository.query.QueryLookupStrategy.Key, org.springframework.data.repository.query.EvaluationContextProvider)
|
||||
*/
|
||||
@Override
|
||||
protected Optional<QueryLookupStrategy> getQueryLookupStrategy(QueryLookupStrategy.Key key,
|
||||
QueryMethodEvaluationContextProvider evaluationContextProvider) {
|
||||
@@ -88,15 +123,6 @@ public class JdbcRepositoryFactory extends RepositoryFactorySupport {
|
||||
throw new IllegalArgumentException(String.format("Unsupported query lookup strategy %s!", key));
|
||||
}
|
||||
|
||||
return Optional.of(new JdbcQueryLookupStrategy(evaluationContextProvider, context, accessStrategy, rowMapperMap));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param rowMapperMap must not be {@literal null} consider {@link RowMapperMap#EMPTY} instead.
|
||||
*/
|
||||
public void setRowMapperMap(RowMapperMap rowMapperMap) {
|
||||
|
||||
Assert.notNull(rowMapperMap, "RowMapperMap must not be null!");
|
||||
this.rowMapperMap = rowMapperMap;
|
||||
return Optional.of(new JdbcQueryLookupStrategy(context, accessStrategy, rowMapperMap));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@ import org.springframework.util.Assert;
|
||||
* @author Jens Schauder
|
||||
* @author Greg Turnquist
|
||||
* @author Christoph Strobl
|
||||
* @author Oliver Gierke
|
||||
* @since 1.0
|
||||
*/
|
||||
public class JdbcRepositoryFactoryBean<T extends Repository<S, ID>, S, ID extends Serializable> //
|
||||
@@ -47,14 +48,24 @@ public class JdbcRepositoryFactoryBean<T extends Repository<S, ID>, S, ID extend
|
||||
private DataAccessStrategy dataAccessStrategy;
|
||||
private RowMapperMap rowMapperMap = RowMapperMap.EMPTY;
|
||||
|
||||
/**
|
||||
* Creates a new {@link JdbcRepositoryFactoryBean} for the given repository interface.
|
||||
*
|
||||
* @param repositoryInterface must not be {@literal null}.
|
||||
*/
|
||||
JdbcRepositoryFactoryBean(Class<? extends T> repositoryInterface) {
|
||||
super(repositoryInterface);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport#setApplicationEventPublisher(org.springframework.context.ApplicationEventPublisher)
|
||||
*/
|
||||
@Override
|
||||
public void setApplicationEventPublisher(ApplicationEventPublisher publisher) {
|
||||
|
||||
super.setApplicationEventPublisher(publisher);
|
||||
|
||||
this.publisher = publisher;
|
||||
}
|
||||
|
||||
@@ -66,8 +77,8 @@ public class JdbcRepositoryFactoryBean<T extends Repository<S, ID>, S, ID extend
|
||||
@Override
|
||||
protected RepositoryFactorySupport doCreateRepositoryFactory() {
|
||||
|
||||
JdbcRepositoryFactory jdbcRepositoryFactory = new JdbcRepositoryFactory(publisher, mappingContext,
|
||||
dataAccessStrategy);
|
||||
JdbcRepositoryFactory jdbcRepositoryFactory = new JdbcRepositoryFactory(dataAccessStrategy, mappingContext,
|
||||
publisher);
|
||||
jdbcRepositoryFactory.setRowMapperMap(rowMapperMap);
|
||||
|
||||
return jdbcRepositoryFactory;
|
||||
@@ -97,6 +108,10 @@ public class JdbcRepositoryFactoryBean<T extends Repository<S, ID>, S, ID extend
|
||||
this.rowMapperMap = rowMapperMap;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport#afterPropertiesSet()
|
||||
*/
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
|
||||
@@ -104,13 +119,12 @@ public class JdbcRepositoryFactoryBean<T extends Repository<S, ID>, S, ID extend
|
||||
|
||||
if (dataAccessStrategy == null) {
|
||||
|
||||
dataAccessStrategy = new DefaultDataAccessStrategy( //
|
||||
new SqlGeneratorSource(mappingContext), //
|
||||
mappingContext);
|
||||
SqlGeneratorSource sqlGeneratorSource = new SqlGeneratorSource(mappingContext);
|
||||
this.dataAccessStrategy = new DefaultDataAccessStrategy(sqlGeneratorSource, mappingContext);
|
||||
}
|
||||
|
||||
if (rowMapperMap == null) {
|
||||
rowMapperMap = RowMapperMap.EMPTY;
|
||||
this.rowMapperMap = RowMapperMap.EMPTY;
|
||||
}
|
||||
|
||||
super.afterPropertiesSet();
|
||||
|
||||
@@ -21,6 +21,7 @@ import org.springframework.data.jdbc.mapping.model.JdbcMappingContext;
|
||||
import org.springframework.data.repository.query.RepositoryQuery;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
@@ -29,6 +30,7 @@ import org.springframework.util.StringUtils;
|
||||
*
|
||||
* @author Jens Schauder
|
||||
* @author Kazuki Shimizu
|
||||
* @author Oliver Gierke
|
||||
* @since 1.0
|
||||
*/
|
||||
class JdbcRepositoryQuery implements RepositoryQuery {
|
||||
@@ -39,26 +41,36 @@ class JdbcRepositoryQuery implements RepositoryQuery {
|
||||
private final JdbcMappingContext context;
|
||||
private final RowMapper<?> rowMapper;
|
||||
|
||||
JdbcRepositoryQuery(JdbcQueryMethod queryMethod, JdbcMappingContext context, RowMapper defaultRowMapper) {
|
||||
/**
|
||||
* Creates a new {@link JdbcRepositoryQuery} for the given {@link JdbcQueryMethod}, {@link JdbcMappingContext} and
|
||||
* {@link RowMapper}.
|
||||
*
|
||||
* @param queryMethod must not be {@literal null}.
|
||||
* @param context must not be {@literal null}.
|
||||
* @param defaultRowMapper can be {@literal null} (only in case of a modifying query).
|
||||
*/
|
||||
JdbcRepositoryQuery(JdbcQueryMethod queryMethod, JdbcMappingContext context, RowMapper<?> defaultRowMapper) {
|
||||
|
||||
Assert.notNull(queryMethod, "Query method must not be null!");
|
||||
Assert.notNull(context, "JdbcMappingContext must not be null!");
|
||||
|
||||
if (!queryMethod.isModifyingQuery()) {
|
||||
Assert.notNull(defaultRowMapper, "RowMapper must not be null!");
|
||||
}
|
||||
|
||||
this.queryMethod = queryMethod;
|
||||
this.context = context;
|
||||
this.rowMapper = createRowMapper(queryMethod, defaultRowMapper);
|
||||
}
|
||||
|
||||
private static RowMapper<?> createRowMapper(JdbcQueryMethod queryMethod, RowMapper defaultRowMapper) {
|
||||
|
||||
Class<?> rowMapperClass = queryMethod.getRowMapperClass();
|
||||
|
||||
return rowMapperClass == null || rowMapperClass == RowMapper.class ? defaultRowMapper
|
||||
: (RowMapper<?>) BeanUtils.instantiateClass(rowMapperClass);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.query.RepositoryQuery#execute(java.lang.Object[])
|
||||
*/
|
||||
@Override
|
||||
public Object execute(Object[] objects) {
|
||||
|
||||
String query = determineQuery();
|
||||
|
||||
MapSqlParameterSource parameters = bindParameters(objects);
|
||||
|
||||
if (queryMethod.isModifyingQuery()) {
|
||||
@@ -80,6 +92,10 @@ class JdbcRepositoryQuery implements RepositoryQuery {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.query.RepositoryQuery#getQueryMethod()
|
||||
*/
|
||||
@Override
|
||||
public JdbcQueryMethod getQueryMethod() {
|
||||
return queryMethod;
|
||||
@@ -92,17 +108,29 @@ class JdbcRepositoryQuery implements RepositoryQuery {
|
||||
if (StringUtils.isEmpty(query)) {
|
||||
throw new IllegalStateException(String.format("No query specified on %s", queryMethod.getName()));
|
||||
}
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
private MapSqlParameterSource bindParameters(Object[] objects) {
|
||||
|
||||
MapSqlParameterSource parameters = new MapSqlParameterSource();
|
||||
|
||||
queryMethod.getParameters().getBindableParameters().forEach(p -> {
|
||||
|
||||
String parameterName = p.getName().orElseThrow(() -> new IllegalStateException(PARAMETER_NEEDS_TO_BE_NAMED));
|
||||
parameters.addValue(parameterName, objects[p.getIndex()]);
|
||||
});
|
||||
|
||||
return parameters;
|
||||
}
|
||||
|
||||
private static RowMapper<?> createRowMapper(JdbcQueryMethod queryMethod, RowMapper<?> defaultRowMapper) {
|
||||
|
||||
Class<?> rowMapperClass = queryMethod.getRowMapperClass();
|
||||
|
||||
return rowMapperClass == null || rowMapperClass == RowMapper.class //
|
||||
? defaultRowMapper //
|
||||
: (RowMapper<?>) BeanUtils.instantiateClass(rowMapperClass);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user