Skip to content

Commit

Permalink
spring-projectsGH-1006 included QueryMappingConfiguration for all par…
Browse files Browse the repository at this point in the history
…t tree queries
  • Loading branch information
mipo256 committed Sep 20, 2024
1 parent 25effcd commit a481a59
Show file tree
Hide file tree
Showing 20 changed files with 212 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package org.springframework.data.jdbc.core.convert;

import org.springframework.data.jdbc.repository.QueryMappingConfiguration;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;
import org.springframework.util.Assert;

Expand All @@ -25,6 +26,7 @@
* {@link DataAccessStrategy} for consistent access strategy creation.
*
* @author Mark Paluch
* @author Mikhail Polivakha
* @since 3.2
*/
public class DataAccessStrategyFactory {
Expand All @@ -34,6 +36,7 @@ public class DataAccessStrategyFactory {
private final NamedParameterJdbcOperations operations;
private final SqlParametersFactory sqlParametersFactory;
private final InsertStrategyFactory insertStrategyFactory;
private final QueryMappingConfiguration queryMappingConfiguration;

/**
* Creates a new {@link DataAccessStrategyFactory}.
Expand All @@ -46,7 +49,7 @@ public class DataAccessStrategyFactory {
*/
public DataAccessStrategyFactory(SqlGeneratorSource sqlGeneratorSource, JdbcConverter converter,
NamedParameterJdbcOperations operations, SqlParametersFactory sqlParametersFactory,
InsertStrategyFactory insertStrategyFactory) {
InsertStrategyFactory insertStrategyFactory, QueryMappingConfiguration queryMappingConfiguration) {

Assert.notNull(sqlGeneratorSource, "SqlGeneratorSource must not be null");
Assert.notNull(converter, "JdbcConverter must not be null");
Expand All @@ -59,6 +62,7 @@ public DataAccessStrategyFactory(SqlGeneratorSource sqlGeneratorSource, JdbcConv
this.operations = operations;
this.sqlParametersFactory = sqlParametersFactory;
this.insertStrategyFactory = insertStrategyFactory;
this.queryMappingConfiguration = queryMappingConfiguration;
}

/**
Expand All @@ -70,7 +74,7 @@ public DataAccessStrategy create() {

DefaultDataAccessStrategy defaultDataAccessStrategy = new DefaultDataAccessStrategy(sqlGeneratorSource,
this.converter.getMappingContext(), this.converter, this.operations, sqlParametersFactory,
insertStrategyFactory);
insertStrategyFactory, queryMappingConfiguration);

if (this.converter.getMappingContext().isSingleQueryLoadingEnabled()) {
return new SingleQueryFallbackDataAccessStrategy(sqlGeneratorSource, converter, operations,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.springframework.dao.OptimisticLockingFailureException;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jdbc.repository.QueryMappingConfiguration;
import org.springframework.data.mapping.PersistentPropertyPath;
import org.springframework.data.relational.core.conversion.IdValueSource;
import org.springframework.data.relational.core.mapping.AggregatePath;
Expand Down Expand Up @@ -60,6 +61,7 @@
* @author Radim Tlusty
* @author Chirag Tailor
* @author Diego Krupitza
* @author Mikhail Polivakha
* @since 1.1
*/
public class DefaultDataAccessStrategy implements DataAccessStrategy {
Expand All @@ -71,6 +73,8 @@ public class DefaultDataAccessStrategy implements DataAccessStrategy {
private final SqlParametersFactory sqlParametersFactory;
private final InsertStrategyFactory insertStrategyFactory;

private final QueryMappingConfiguration queryMappingConfiguration;

/**
* Creates a {@link DefaultDataAccessStrategy}
*
Expand All @@ -82,21 +86,23 @@ public class DefaultDataAccessStrategy implements DataAccessStrategy {
*/
public DefaultDataAccessStrategy(SqlGeneratorSource sqlGeneratorSource, RelationalMappingContext context,
JdbcConverter converter, NamedParameterJdbcOperations operations, SqlParametersFactory sqlParametersFactory,
InsertStrategyFactory insertStrategyFactory) {
InsertStrategyFactory insertStrategyFactory, QueryMappingConfiguration queryMappingConfiguration) {

Assert.notNull(sqlGeneratorSource, "SqlGeneratorSource must not be null");
Assert.notNull(context, "RelationalMappingContext must not be null");
Assert.notNull(converter, "JdbcConverter must not be null");
Assert.notNull(operations, "NamedParameterJdbcOperations must not be null");
Assert.notNull(sqlParametersFactory, "SqlParametersFactory must not be null");
Assert.notNull(insertStrategyFactory, "InsertStrategyFactory must not be null");
Assert.notNull(queryMappingConfiguration, "InsertStrategyFactory must not be null");

this.sqlGeneratorSource = sqlGeneratorSource;
this.context = context;
this.converter = converter;
this.operations = operations;
this.sqlParametersFactory = sqlParametersFactory;
this.insertStrategyFactory = insertStrategyFactory;
this.queryMappingConfiguration = queryMappingConfiguration;
}

@Override
Expand Down Expand Up @@ -265,15 +271,15 @@ public <T> T findById(Object id, Class<T> domainType) {
SqlIdentifierParameterSource parameter = sqlParametersFactory.forQueryById(id, domainType, ID_SQL_PARAMETER);

try {
return operations.queryForObject(findOneSql, parameter, getEntityRowMapper(domainType));
return operations.queryForObject(findOneSql, parameter, getRowMapper(domainType));
} catch (EmptyResultDataAccessException e) {
return null;
}
}

@Override
public <T> Iterable<T> findAll(Class<T> domainType) {
return operations.query(sql(domainType).getFindAll(), getEntityRowMapper(domainType));
return operations.query(sql(domainType).getFindAll(), getRowMapper(domainType));
}

@Override
Expand All @@ -285,7 +291,7 @@ public <T> Iterable<T> findAllById(Iterable<?> ids, Class<T> domainType) {

SqlParameterSource parameterSource = sqlParametersFactory.forQueryByIds(ids, domainType);
String findAllInListSql = sql(domainType).getFindAllInList();
return operations.query(findAllInListSql, parameterSource, getEntityRowMapper(domainType));
return operations.query(findAllInListSql, parameterSource, getRowMapper(domainType));
}

@Override
Expand Down Expand Up @@ -339,12 +345,12 @@ public <T> boolean existsById(Object id, Class<T> domainType) {

@Override
public <T> Iterable<T> findAll(Class<T> domainType, Sort sort) {
return operations.query(sql(domainType).getFindAll(sort), getEntityRowMapper(domainType));
return operations.query(sql(domainType).getFindAll(sort), getRowMapper(domainType));
}

@Override
public <T> Iterable<T> findAll(Class<T> domainType, Pageable pageable) {
return operations.query(sql(domainType).getFindAll(pageable), getEntityRowMapper(domainType));
return operations.query(sql(domainType).getFindAll(pageable), getRowMapper(domainType));
}

@Override
Expand All @@ -354,7 +360,7 @@ public <T> Optional<T> findOne(Query query, Class<T> domainType) {
String sqlQuery = sql(domainType).selectByQuery(query, parameterSource);

try {
return Optional.ofNullable(operations.queryForObject(sqlQuery, parameterSource, getEntityRowMapper(domainType)));
return Optional.ofNullable(operations.queryForObject(sqlQuery, parameterSource, getRowMapper(domainType)));
} catch (EmptyResultDataAccessException e) {
return Optional.empty();
}
Expand All @@ -366,7 +372,7 @@ public <T> Iterable<T> findAll(Query query, Class<T> domainType) {
MapSqlParameterSource parameterSource = new MapSqlParameterSource();
String sqlQuery = sql(domainType).selectByQuery(query, parameterSource);

return operations.query(sqlQuery, parameterSource, getEntityRowMapper(domainType));
return operations.query(sqlQuery, parameterSource, getRowMapper(domainType));
}

@Override
Expand All @@ -375,7 +381,7 @@ public <T> Iterable<T> findAll(Query query, Class<T> domainType, Pageable pageab
MapSqlParameterSource parameterSource = new MapSqlParameterSource();
String sqlQuery = sql(domainType).selectByQuery(query, parameterSource, pageable);

return operations.query(sqlQuery, parameterSource, getEntityRowMapper(domainType));
return operations.query(sqlQuery, parameterSource, getRowMapper(domainType));
}

@Override
Expand Down Expand Up @@ -404,7 +410,13 @@ public <T> long count(Query query, Class<T> domainType) {
return result;
}

private <T> EntityRowMapper<T> getEntityRowMapper(Class<T> domainType) {
private <T> RowMapper<? extends T> getRowMapper(Class<T> domainType) {
RowMapper<? extends T> targetRowMapper;

if ((targetRowMapper = queryMappingConfiguration.getRowMapper(domainType)) != null) {
return targetRowMapper;
}

return new EntityRowMapper<>(getRequiredPersistentEntity(domainType), converter);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jdbc.core.convert.*;
import org.springframework.data.jdbc.repository.QueryMappingConfiguration;
import org.springframework.data.mapping.PersistentPropertyPath;
import org.springframework.data.mapping.PropertyPath;
import org.springframework.data.relational.core.conversion.IdValueSource;
Expand Down Expand Up @@ -72,9 +73,10 @@ public class MyBatisDataAccessStrategy implements DataAccessStrategy {
* uses a {@link DefaultDataAccessStrategy}
*/
public static DataAccessStrategy createCombinedAccessStrategy(RelationalMappingContext context,
JdbcConverter converter, NamedParameterJdbcOperations operations, SqlSession sqlSession, Dialect dialect) {
JdbcConverter converter, NamedParameterJdbcOperations operations, SqlSession sqlSession,
Dialect dialect, QueryMappingConfiguration queryMappingConfiguration) {
return createCombinedAccessStrategy(context, converter, operations, sqlSession, NamespaceStrategy.DEFAULT_INSTANCE,
dialect);
dialect, queryMappingConfiguration);
}

/**
Expand All @@ -83,7 +85,7 @@ public static DataAccessStrategy createCombinedAccessStrategy(RelationalMappingC
*/
public static DataAccessStrategy createCombinedAccessStrategy(RelationalMappingContext context,
JdbcConverter converter, NamedParameterJdbcOperations operations, SqlSession sqlSession,
NamespaceStrategy namespaceStrategy, Dialect dialect) {
NamespaceStrategy namespaceStrategy, Dialect dialect, QueryMappingConfiguration queryMappingConfiguration) {

SqlGeneratorSource sqlGeneratorSource = new SqlGeneratorSource(context, converter, dialect);
SqlParametersFactory sqlParametersFactory = new SqlParametersFactory(context, converter);
Expand All @@ -94,7 +96,8 @@ public static DataAccessStrategy createCombinedAccessStrategy(RelationalMappingC
converter, //
operations, //
sqlParametersFactory, //
insertStrategyFactory //
insertStrategyFactory, //
queryMappingConfiguration //
).create();

// the DefaultDataAccessStrategy needs a reference to the returned DataAccessStrategy. This creates a dependency
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
import org.springframework.data.jdbc.core.dialect.JdbcDialect;
import org.springframework.data.jdbc.core.mapping.JdbcMappingContext;
import org.springframework.data.jdbc.core.mapping.JdbcSimpleTypes;
import org.springframework.data.jdbc.repository.QueryMappingConfiguration;
import org.springframework.data.mapping.model.SimpleTypeHolder;
import org.springframework.data.relational.RelationalManagedTypes;
import org.springframework.data.relational.core.conversion.RelationalConverter;
Expand All @@ -61,6 +62,7 @@
* @author Christoph Strobl
* @author Myeonghyeon Lee
* @author Chirag Tailor
* @author Mikhail Polivakha
* @since 1.1
*/
@Configuration(proxyBeanMethods = false)
Expand All @@ -70,6 +72,8 @@ public class AbstractJdbcConfiguration implements ApplicationContextAware {

private ApplicationContext applicationContext;

private QueryMappingConfiguration queryMappingConfiguration;

/**
* Returns the base packages to scan for JDBC mapped entities at startup. Returns the package name of the
* configuration class' (the concrete class, not this one here) by default. So if you have a
Expand Down Expand Up @@ -208,7 +212,9 @@ public DataAccessStrategy dataAccessStrategyBean(NamedParameterJdbcOperations op
SqlGeneratorSource sqlGeneratorSource = new SqlGeneratorSource(context, jdbcConverter, dialect);
DataAccessStrategyFactory factory = new DataAccessStrategyFactory(sqlGeneratorSource, jdbcConverter, operations,
new SqlParametersFactory(context, jdbcConverter),
new InsertStrategyFactory(operations, dialect));
new InsertStrategyFactory(operations, dialect),
this.queryMappingConfiguration
);

return factory.create();
}
Expand All @@ -232,6 +238,10 @@ public void setApplicationContext(ApplicationContext applicationContext) throws
this.applicationContext = applicationContext;
}

public void setQueryMappingConfiguration(Optional<QueryMappingConfiguration> queryMappingConfiguration) throws BeansException {
this.queryMappingConfiguration = queryMappingConfiguration.orElse(QueryMappingConfiguration.EMPTY);
}

/**
* Scans the mapping base package for classes annotated with {@link Table}. By default, it scans for entities in all
* packages returned by {@link #getMappingBasePackages()}.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
*/
package org.springframework.data.jdbc.repository.config;

import java.util.Optional;

import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
Expand All @@ -23,25 +25,29 @@
import org.springframework.data.jdbc.core.convert.JdbcConverter;
import org.springframework.data.jdbc.core.mapping.JdbcMappingContext;
import org.springframework.data.jdbc.mybatis.MyBatisDataAccessStrategy;
import org.springframework.data.jdbc.repository.QueryMappingConfiguration;
import org.springframework.data.relational.core.dialect.Dialect;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;

/**
* Configuration class tweaking Spring Data JDBC to use a {@link MyBatisDataAccessStrategy} instead of the default one.
*
* @author Oliver Drotbohm
* @author Mikhail Polivakha
* @since 1.1
*/
@Configuration(proxyBeanMethods = false)
public class MyBatisJdbcConfiguration extends AbstractJdbcConfiguration {

private @Autowired SqlSession session;

private @Autowired Optional<QueryMappingConfiguration> queryMappingConfiguration;

@Bean
@Override
public DataAccessStrategy dataAccessStrategyBean(NamedParameterJdbcOperations operations, JdbcConverter jdbcConverter,
JdbcMappingContext context, Dialect dialect) {

return MyBatisDataAccessStrategy.createCombinedAccessStrategy(context, jdbcConverter, operations, session, dialect);
return MyBatisDataAccessStrategy.createCombinedAccessStrategy(context, jdbcConverter, operations, session, dialect, queryMappingConfiguration.orElse(QueryMappingConfiguration.EMPTY));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
* @author Mark Paluch
* @author Hebert Coelho
* @author Chirag Tailor
* @author Mikhail Polivakha
*/
public class JdbcRepositoryFactoryBean<T extends Repository<S, ID>, S, ID extends Serializable>
extends TransactionalRepositoryFactoryBeanSupport<T, S, ID> implements ApplicationEventPublisherAware {
Expand Down Expand Up @@ -161,11 +162,15 @@ public void afterPropertiesSet() {

if (this.operations == null) {

Assert.state(beanFactory != null, "If no JdbcOperations are set a BeanFactory must be available");
Assert.state( beanFactory != null, "If no JdbcOperations are set a BeanFactory must be available");

this.operations = beanFactory.getBean(NamedParameterJdbcOperations.class);
}

if (this.queryMappingConfiguration == null) {
this.queryMappingConfiguration = QueryMappingConfiguration.EMPTY;
}

if (this.dataAccessStrategy == null) {

Assert.state(beanFactory != null, "If no DataAccessStrategy is set a BeanFactory must be available");
Expand All @@ -181,16 +186,12 @@ public void afterPropertiesSet() {
InsertStrategyFactory insertStrategyFactory = new InsertStrategyFactory(this.operations, this.dialect);

DataAccessStrategyFactory factory = new DataAccessStrategyFactory(sqlGeneratorSource, this.converter,
this.operations, sqlParametersFactory, insertStrategyFactory);
this.operations, sqlParametersFactory, insertStrategyFactory, queryMappingConfiguration);

return factory.create();
});
}

if (this.queryMappingConfiguration == null) {
this.queryMappingConfiguration = QueryMappingConfiguration.EMPTY;
}

if (beanFactory != null) {
entityCallbacks = EntityCallbacks.create(beanFactory);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import org.junit.jupiter.api.Test;
import org.springframework.data.annotation.Id;
import org.springframework.data.jdbc.core.mapping.JdbcMappingContext;
import org.springframework.data.jdbc.repository.QueryMappingConfiguration;
import org.springframework.data.relational.core.conversion.IdValueSource;
import org.springframework.data.relational.core.dialect.Dialect;
import org.springframework.data.relational.core.dialect.HsqlDbDialect;
Expand All @@ -40,6 +41,7 @@
* @author Myat Min
* @author Radim Tlusty
* @author Chirag Tailor
* @author Mikhail Polivakha
*/
class DefaultDataAccessStrategyUnitTests {

Expand All @@ -66,7 +68,8 @@ void before() {
converter, //
namedJdbcOperations, //
sqlParametersFactory, //
insertStrategyFactory).create();
insertStrategyFactory,
QueryMappingConfiguration.EMPTY).create();

relationResolver.setDelegate(accessStrategy);

Expand Down
Loading

0 comments on commit a481a59

Please sign in to comment.