Create spring-boot-data-jdbc module

This commit is contained in:
Stéphane Nicoll
2025-03-28 16:27:46 +01:00
committed by Phillip Webb
parent 1b30f838c1
commit cacaeacbe9
20 changed files with 79 additions and 24 deletions

View File

@@ -0,0 +1,44 @@
/*
* Copyright 2012-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.data.jdbc.autoconfigure;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* Configuration properties for Spring Data JDBC.
*
* @author Jens Schauder
* @since 3.3.0
*/
@ConfigurationProperties("spring.data.jdbc")
public class JdbcDataProperties {
/**
* Dialect to use. By default, the dialect is determined by inspecting the database
* connection.
*/
private JdbcDatabaseDialect dialect;
public JdbcDatabaseDialect getDialect() {
return this.dialect;
}
public void setDialect(JdbcDatabaseDialect dialect) {
this.dialect = dialect;
}
}

View File

@@ -0,0 +1,86 @@
/*
* Copyright 2012-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.data.jdbc.autoconfigure;
import org.springframework.data.jdbc.core.dialect.JdbcDb2Dialect;
import org.springframework.data.jdbc.core.dialect.JdbcH2Dialect;
import org.springframework.data.jdbc.core.dialect.JdbcHsqlDbDialect;
import org.springframework.data.jdbc.core.dialect.JdbcMySqlDialect;
import org.springframework.data.jdbc.core.dialect.JdbcOracleDialect;
import org.springframework.data.jdbc.core.dialect.JdbcPostgresDialect;
import org.springframework.data.jdbc.core.dialect.JdbcSqlServerDialect;
import org.springframework.data.relational.core.dialect.Dialect;
/**
* List of database dialects that can be configured in Boot for use with Spring Data JDBC.
*
* @author Jens Schauder
* @since 3.3.0
*/
public enum JdbcDatabaseDialect {
/**
* Provides an instance of {@link JdbcDb2Dialect}.
*/
DB2(JdbcDb2Dialect.INSTANCE),
/**
* Provides an instance of {@link JdbcH2Dialect}.
*/
H2(JdbcH2Dialect.INSTANCE),
/**
* Provides an instance of {@link JdbcHsqlDbDialect}.
*/
HSQL(JdbcHsqlDbDialect.INSTANCE),
/**
* Provides an instance of {@link JdbcMySqlDialect}.
*/
MARIA(JdbcMySqlDialect.INSTANCE),
/**
* Provides an instance of {@link JdbcMySqlDialect}.
*/
MYSQL(JdbcMySqlDialect.INSTANCE),
/**
* Provides an instance of {@link JdbcOracleDialect}.
*/
ORACLE(JdbcOracleDialect.INSTANCE),
/**
* Provides an instance of {@link JdbcPostgresDialect}.
*/
POSTGRESQL(JdbcPostgresDialect.INSTANCE),
/**
* Provides an instance of {@link JdbcSqlServerDialect}.
*/
SQL_SERVER(JdbcSqlServerDialect.INSTANCE);
private final Dialect dialect;
JdbcDatabaseDialect(Dialect dialect) {
this.dialect = dialect;
}
final Dialect getDialect() {
return this.dialect;
}
}

View File

@@ -0,0 +1,155 @@
/*
* Copyright 2012-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.data.jdbc.autoconfigure;
import java.util.Optional;
import java.util.Set;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.domain.EntityScanner;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.jdbc.autoconfigure.DataSourceTransactionManagerAutoConfiguration;
import org.springframework.boot.jdbc.autoconfigure.JdbcTemplateAutoConfiguration;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.jdbc.core.JdbcAggregateTemplate;
import org.springframework.data.jdbc.core.convert.DataAccessStrategy;
import org.springframework.data.jdbc.core.convert.JdbcConverter;
import org.springframework.data.jdbc.core.convert.JdbcCustomConversions;
import org.springframework.data.jdbc.core.convert.RelationResolver;
import org.springframework.data.jdbc.core.mapping.JdbcMappingContext;
import org.springframework.data.jdbc.repository.config.AbstractJdbcConfiguration;
import org.springframework.data.jdbc.repository.config.EnableJdbcRepositories;
import org.springframework.data.jdbc.repository.config.JdbcRepositoryConfigExtension;
import org.springframework.data.relational.RelationalManagedTypes;
import org.springframework.data.relational.core.dialect.Dialect;
import org.springframework.data.relational.core.mapping.NamingStrategy;
import org.springframework.data.relational.core.mapping.Table;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;
import org.springframework.transaction.PlatformTransactionManager;
/**
* {@link EnableAutoConfiguration Auto-configuration} for Spring Data's JDBC Repositories.
* <p>
* Once in effect, the auto-configuration is the equivalent of enabling JDBC repositories
* using the {@link EnableJdbcRepositories @EnableJdbcRepositories} annotation and
* providing an {@link AbstractJdbcConfiguration} subclass.
*
* @author Andy Wilkinson
* @author Stephane Nicoll
* @author Mark Paluch
* @author Jens Schauder
* @since 2.1.0
* @see EnableJdbcRepositories
*/
@AutoConfiguration(after = { JdbcTemplateAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class })
@ConditionalOnBean({ NamedParameterJdbcOperations.class, PlatformTransactionManager.class })
@ConditionalOnClass({ NamedParameterJdbcOperations.class, AbstractJdbcConfiguration.class })
@ConditionalOnBooleanProperty(name = "spring.data.jdbc.repositories.enabled", matchIfMissing = true)
@EnableConfigurationProperties(JdbcDataProperties.class)
public class JdbcRepositoriesAutoConfiguration {
@Configuration(proxyBeanMethods = false)
@ConditionalOnMissingBean(JdbcRepositoryConfigExtension.class)
@Import(JdbcRepositoriesRegistrar.class)
static class JdbcRepositoriesConfiguration {
}
@Configuration(proxyBeanMethods = false)
@ConditionalOnMissingBean(AbstractJdbcConfiguration.class)
static class SpringBootJdbcConfiguration extends AbstractJdbcConfiguration {
private final ApplicationContext applicationContext;
private final JdbcDataProperties properties;
SpringBootJdbcConfiguration(ApplicationContext applicationContext, JdbcDataProperties properties) {
this.applicationContext = applicationContext;
this.properties = properties;
}
@Override
protected Set<Class<?>> getInitialEntitySet() throws ClassNotFoundException {
return new EntityScanner(this.applicationContext).scan(Table.class);
}
@Override
@Bean
@ConditionalOnMissingBean
public RelationalManagedTypes jdbcManagedTypes() throws ClassNotFoundException {
return super.jdbcManagedTypes();
}
@Override
@Bean
@ConditionalOnMissingBean
public JdbcMappingContext jdbcMappingContext(Optional<NamingStrategy> namingStrategy,
JdbcCustomConversions customConversions, RelationalManagedTypes jdbcManagedTypes) {
return super.jdbcMappingContext(namingStrategy, customConversions, jdbcManagedTypes);
}
@Override
@Bean
@ConditionalOnMissingBean
public JdbcConverter jdbcConverter(JdbcMappingContext mappingContext, NamedParameterJdbcOperations operations,
@Lazy RelationResolver relationResolver, JdbcCustomConversions conversions, Dialect dialect) {
return super.jdbcConverter(mappingContext, operations, relationResolver, conversions, dialect);
}
@Override
@Bean
@ConditionalOnMissingBean
public JdbcCustomConversions jdbcCustomConversions() {
return super.jdbcCustomConversions();
}
@Override
@Bean
@ConditionalOnMissingBean
public JdbcAggregateTemplate jdbcAggregateTemplate(ApplicationContext applicationContext,
JdbcMappingContext mappingContext, JdbcConverter converter, DataAccessStrategy dataAccessStrategy) {
return super.jdbcAggregateTemplate(applicationContext, mappingContext, converter, dataAccessStrategy);
}
@Override
@Bean
@ConditionalOnMissingBean
public DataAccessStrategy dataAccessStrategyBean(NamedParameterJdbcOperations operations,
JdbcConverter jdbcConverter, JdbcMappingContext context, Dialect dialect) {
return super.dataAccessStrategyBean(operations, jdbcConverter, context, dialect);
}
@Override
@Bean
@ConditionalOnMissingBean
public Dialect jdbcDialect(NamedParameterJdbcOperations operations) {
JdbcDatabaseDialect dialect = this.properties.getDialect();
return (dialect != null) ? dialect.getDialect() : super.jdbcDialect(operations);
}
}
}

View File

@@ -0,0 +1,55 @@
/*
* Copyright 2012-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.data.jdbc.autoconfigure;
import java.lang.annotation.Annotation;
import org.springframework.boot.autoconfigure.data.AbstractRepositoryConfigurationSourceSupport;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.data.jdbc.repository.config.EnableJdbcRepositories;
import org.springframework.data.jdbc.repository.config.JdbcRepositoryConfigExtension;
import org.springframework.data.repository.config.RepositoryConfigurationExtension;
/**
* {@link ImportBeanDefinitionRegistrar} used to auto-configure Spring Data JDBC
* Repositories.
*
* @author Andy Wilkinson
*/
class JdbcRepositoriesRegistrar extends AbstractRepositoryConfigurationSourceSupport {
@Override
protected Class<? extends Annotation> getAnnotation() {
return EnableJdbcRepositories.class;
}
@Override
protected Class<?> getConfiguration() {
return EnableJdbcRepositoriesConfiguration.class;
}
@Override
protected RepositoryConfigurationExtension getRepositoryConfigurationExtension() {
return new JdbcRepositoryConfigExtension();
}
@EnableJdbcRepositories
private static final class EnableJdbcRepositoriesConfiguration {
}
}

View File

@@ -0,0 +1,20 @@
/*
* Copyright 2012-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Auto-configuration for Spring Data JDBC.
*/
package org.springframework.boot.data.jdbc.autoconfigure;

View File

@@ -0,0 +1,11 @@
{
"groups": [],
"properties": [
{
"name": "spring.data.jdbc.repositories.enabled",
"type": "java.lang.Boolean",
"description": "Whether to enable JDBC repositories.",
"defaultValue": true
}
]
}

View File

@@ -0,0 +1 @@
org.springframework.boot.data.jdbc.autoconfigure.JdbcRepositoriesAutoConfiguration

View File

@@ -0,0 +1,314 @@
/*
* Copyright 2012-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.data.jdbc.autoconfigure;
import java.util.function.Function;
import javax.sql.DataSource;
import org.junit.jupiter.api.Test;
import org.mockito.Answers;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage;
import org.springframework.boot.data.jdbc.domain.city.City;
import org.springframework.boot.data.jdbc.domain.city.CityRepository;
import org.springframework.boot.data.jdbc.domain.empty.EmptyDataPackage;
import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration;
import org.springframework.boot.jdbc.autoconfigure.DataSourceInitializationAutoConfiguration;
import org.springframework.boot.jdbc.autoconfigure.DataSourceTransactionManagerAutoConfiguration;
import org.springframework.boot.jdbc.autoconfigure.JdbcTemplateAutoConfiguration;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.boot.testsupport.classpath.resources.WithResource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.domain.ManagedTypes;
import org.springframework.data.jdbc.core.JdbcAggregateTemplate;
import org.springframework.data.jdbc.core.convert.DataAccessStrategy;
import org.springframework.data.jdbc.core.convert.JdbcConverter;
import org.springframework.data.jdbc.core.convert.JdbcCustomConversions;
import org.springframework.data.jdbc.core.dialect.JdbcPostgresDialect;
import org.springframework.data.jdbc.core.mapping.JdbcMappingContext;
import org.springframework.data.jdbc.repository.config.AbstractJdbcConfiguration;
import org.springframework.data.jdbc.repository.config.EnableJdbcRepositories;
import org.springframework.data.relational.RelationalManagedTypes;
import org.springframework.data.relational.core.dialect.Dialect;
import org.springframework.data.repository.Repository;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;
import org.springframework.test.util.ReflectionTestUtils;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
/**
* Tests for {@link JdbcRepositoriesAutoConfiguration}.
*
* @author Andy Wilkinson
* @author Stephane Nicoll
* @author Mark Paluch
* @author Jens Schauder
*/
@WithResource(name = "schema.sql", content = """
CREATE TABLE CITY (
id INTEGER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
name VARCHAR(30),
state VARCHAR(30),
country VARCHAR(30),
map VARCHAR(30)
);
""")
@WithResource(name = "data.sql",
content = "INSERT INTO CITY (ID, NAME, STATE, COUNTRY, MAP) values (2000, 'Washington', 'DC', 'US', 'Google');")
class JdbcRepositoriesAutoConfigurationTests {
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(JdbcRepositoriesAutoConfiguration.class));
@Test
void backsOffWithNoDataSource() {
this.contextRunner.withUserConfiguration(TestConfiguration.class)
.run((context) -> assertThat(context).doesNotHaveBean(AbstractJdbcConfiguration.class));
}
@Test
void backsOffWithNoJdbcOperations() {
this.contextRunner.with(database()).withUserConfiguration(TestConfiguration.class).run((context) -> {
assertThat(context).hasSingleBean(DataSource.class);
assertThat(context).doesNotHaveBean(AbstractJdbcConfiguration.class);
});
}
@Test
void backsOffWithNoTransactionManager() {
this.contextRunner.with(database())
.withConfiguration(AutoConfigurations.of(JdbcTemplateAutoConfiguration.class))
.withUserConfiguration(TestConfiguration.class)
.run((context) -> {
assertThat(context).hasSingleBean(DataSource.class);
assertThat(context).hasSingleBean(NamedParameterJdbcOperations.class);
assertThat(context).doesNotHaveBean(AbstractJdbcConfiguration.class);
});
}
@Test
void basicAutoConfiguration() {
this.contextRunner.with(database())
.withConfiguration(AutoConfigurations.of(JdbcTemplateAutoConfiguration.class,
DataSourceTransactionManagerAutoConfiguration.class))
.withUserConfiguration(TestConfiguration.class)
.run((context) -> {
assertThat(context).hasSingleBean(AbstractJdbcConfiguration.class);
assertThat(context).hasSingleBean(CityRepository.class);
assertThat(context.getBean(CityRepository.class).findById(2000L)).isPresent();
});
}
@Test
void entityScanShouldSetManagedTypes() {
this.contextRunner.with(database())
.withConfiguration(AutoConfigurations.of(JdbcTemplateAutoConfiguration.class,
DataSourceTransactionManagerAutoConfiguration.class))
.withUserConfiguration(TestConfiguration.class)
.run((context) -> {
JdbcMappingContext mappingContext = context.getBean(JdbcMappingContext.class);
ManagedTypes managedTypes = (ManagedTypes) ReflectionTestUtils.getField(mappingContext, "managedTypes");
assertThat(managedTypes.toList()).containsOnly(City.class);
});
}
@Test
void autoConfigurationWithNoRepositories() {
this.contextRunner.with(database())
.withConfiguration(AutoConfigurations.of(JdbcTemplateAutoConfiguration.class,
DataSourceTransactionManagerAutoConfiguration.class))
.withUserConfiguration(EmptyConfiguration.class)
.run((context) -> {
assertThat(context).hasSingleBean(AbstractJdbcConfiguration.class);
assertThat(context).doesNotHaveBean(Repository.class);
});
}
@Test
void honoursUsersEnableJdbcRepositoriesConfiguration() {
this.contextRunner.with(database())
.withConfiguration(AutoConfigurations.of(JdbcTemplateAutoConfiguration.class,
DataSourceTransactionManagerAutoConfiguration.class))
.withUserConfiguration(EnableRepositoriesConfiguration.class)
.run((context) -> {
assertThat(context).hasSingleBean(AbstractJdbcConfiguration.class);
assertThat(context).hasSingleBean(CityRepository.class);
assertThat(context.getBean(CityRepository.class).findById(2000L)).isPresent();
});
}
@Test
void allowsUserToDefineCustomRelationalManagedTypes() {
allowsUserToDefineCustomBean(RelationalManagedTypesConfiguration.class, RelationalManagedTypes.class,
"customRelationalManagedTypes");
}
@Test
void allowsUserToDefineCustomJdbcMappingContext() {
allowsUserToDefineCustomBean(JdbcMappingContextConfiguration.class, JdbcMappingContext.class,
"customJdbcMappingContext");
}
@Test
void allowsUserToDefineCustomJdbcConverter() {
allowsUserToDefineCustomBean(JdbcConverterConfiguration.class, JdbcConverter.class, "customJdbcConverter");
}
@Test
void allowsUserToDefineCustomJdbcCustomConversions() {
allowsUserToDefineCustomBean(JdbcCustomConversionsConfiguration.class, JdbcCustomConversions.class,
"customJdbcCustomConversions");
}
@Test
void allowsUserToDefineCustomJdbcAggregateTemplate() {
allowsUserToDefineCustomBean(JdbcAggregateTemplateConfiguration.class, JdbcAggregateTemplate.class,
"customJdbcAggregateTemplate");
}
@Test
void allowsUserToDefineCustomDataAccessStrategy() {
allowsUserToDefineCustomBean(DataAccessStrategyConfiguration.class, DataAccessStrategy.class,
"customDataAccessStrategy");
}
@Test
void allowsUserToDefineCustomDialect() {
allowsUserToDefineCustomBean(DialectConfiguration.class, Dialect.class, "customDialect");
}
@Test
void allowsConfigurationOfDialectByProperty() {
this.contextRunner.with(database())
.withPropertyValues("spring.data.jdbc.dialect=postgresql")
.withConfiguration(AutoConfigurations.of(JdbcTemplateAutoConfiguration.class,
DataSourceTransactionManagerAutoConfiguration.class))
.withUserConfiguration(TestConfiguration.class)
.run((context) -> assertThat(context).hasSingleBean(JdbcPostgresDialect.class));
}
private void allowsUserToDefineCustomBean(Class<?> configuration, Class<?> beanType, String beanName) {
this.contextRunner.with(database())
.withConfiguration(AutoConfigurations.of(JdbcTemplateAutoConfiguration.class,
DataSourceTransactionManagerAutoConfiguration.class))
.withUserConfiguration(configuration, EmptyConfiguration.class)
.run((context) -> {
assertThat(context).hasSingleBean(beanType);
assertThat(context).hasBean(beanName);
});
}
private Function<ApplicationContextRunner, ApplicationContextRunner> database() {
return (runner) -> runner
.withConfiguration(AutoConfigurations.of(DataSourceAutoConfiguration.class,
DataSourceInitializationAutoConfiguration.class))
.withPropertyValues("spring.sql.init.schema-locations=classpath:schema.sql",
"spring.sql.init.data-locations=classpath:data.sql", "spring.datasource.generate-unique-name:true");
}
@TestAutoConfigurationPackage(City.class)
static class TestConfiguration {
}
@Configuration(proxyBeanMethods = false)
@TestAutoConfigurationPackage(EmptyDataPackage.class)
static class EmptyConfiguration {
}
@TestAutoConfigurationPackage(EmptyDataPackage.class)
@EnableJdbcRepositories(basePackageClasses = City.class)
static class EnableRepositoriesConfiguration {
}
@Configuration(proxyBeanMethods = false)
static class RelationalManagedTypesConfiguration {
@Bean
RelationalManagedTypes customRelationalManagedTypes() {
return RelationalManagedTypes.empty();
}
}
@Configuration(proxyBeanMethods = false)
static class JdbcMappingContextConfiguration {
@Bean
JdbcMappingContext customJdbcMappingContext() {
return mock(JdbcMappingContext.class, Answers.RETURNS_MOCKS);
}
}
@Configuration(proxyBeanMethods = false)
static class JdbcConverterConfiguration {
@Bean
JdbcConverter customJdbcConverter() {
return mock(JdbcConverter.class, Answers.RETURNS_MOCKS);
}
}
@Configuration(proxyBeanMethods = false)
static class JdbcCustomConversionsConfiguration {
@Bean
JdbcCustomConversions customJdbcCustomConversions() {
return mock(JdbcCustomConversions.class, Answers.RETURNS_MOCKS);
}
}
@Configuration(proxyBeanMethods = false)
static class JdbcAggregateTemplateConfiguration {
@Bean
JdbcAggregateTemplate customJdbcAggregateTemplate() {
return mock(JdbcAggregateTemplate.class, Answers.RETURNS_MOCKS);
}
}
@Configuration(proxyBeanMethods = false)
static class DataAccessStrategyConfiguration {
@Bean
DataAccessStrategy customDataAccessStrategy() {
return mock(DataAccessStrategy.class, Answers.RETURNS_MOCKS);
}
}
@Configuration(proxyBeanMethods = false)
static class DialectConfiguration {
@Bean
Dialect customDialect() {
return mock(Dialect.class, Answers.RETURNS_MOCKS);
}
}
}

View File

@@ -0,0 +1,65 @@
/*
* Copyright 2012-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.data.jdbc.domain.city;
import org.springframework.data.annotation.Id;
import org.springframework.data.relational.core.mapping.Table;
@Table("CITY")
public class City {
@Id
private Long id;
private String name;
private String state;
private String country;
private String map;
protected City() {
}
public City(String name, String country) {
this.name = name;
this.country = country;
}
public String getName() {
return this.name;
}
public String getState() {
return this.state;
}
public String getCountry() {
return this.country;
}
public String getMap() {
return this.map;
}
@Override
public String toString() {
return getName() + "," + getState() + "," + getCountry();
}
}

View File

@@ -0,0 +1,23 @@
/*
* Copyright 2012-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.data.jdbc.domain.city;
import org.springframework.data.repository.CrudRepository;
public interface CityRepository extends CrudRepository<City, Long> {
}

View File

@@ -0,0 +1,21 @@
/*
* Copyright 2012-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.data.jdbc.domain.empty;
public class EmptyDataPackage {
}