Add support for Spring Data JDBC (auto-config, starter, and test slice)

Closes gh-14489
pull/14549/merge
Andy Wilkinson 6 years ago
parent fe75f966ff
commit 4b00dc8a5c

@ -469,6 +469,11 @@
<artifactId>spring-data-cassandra</artifactId> <artifactId>spring-data-cassandra</artifactId>
<optional>true</optional> <optional>true</optional>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jdbc</artifactId>
<optional>true</optional>
</dependency>
<dependency> <dependency>
<groupId>org.springframework.data</groupId> <groupId>org.springframework.data</groupId>
<artifactId>spring-data-ldap</artifactId> <artifactId>spring-data-ldap</artifactId>

@ -0,0 +1,65 @@
/*
* Copyright 2012-2018 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
*
* http://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.autoconfigure.data.jdbc;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.data.jdbc.repository.config.EnableJdbcRepositories;
import org.springframework.data.jdbc.repository.config.JdbcConfiguration;
import org.springframework.data.jdbc.repository.config.JdbcRepositoryConfigExtension;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;
/**
* {@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 org.springframework.data.jdbc.repository.config.EnableJdbcRepositories}
* annotation and providing a {@link JdbcConfiguration} subclass.
*
* @author Andy Wilkinson
* @since 2.1.0
* @see EnableJdbcRepositories
*/
@Configuration
@ConditionalOnBean(NamedParameterJdbcOperations.class)
@ConditionalOnClass({ NamedParameterJdbcOperations.class, JdbcConfiguration.class })
@ConditionalOnProperty(prefix = "spring.data.jdbc.repositories", name = "enabled", havingValue = "true", matchIfMissing = true)
@AutoConfigureAfter(JdbcTemplateAutoConfiguration.class)
public class JdbcRepositoriesAutoConfiguration {
@Configuration
@ConditionalOnMissingBean(JdbcRepositoryConfigExtension.class)
@Import(JdbcRepositoriesAutoConfigureRegistrar.class)
static class JdbcRepositoriesConfiguration {
}
@Configuration
@ConditionalOnMissingBean(JdbcConfiguration.class)
static class SpringBootJdbcConfiguration extends JdbcConfiguration {
}
}

@ -0,0 +1,56 @@
/*
* Copyright 2012-2018 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
*
* http://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.autoconfigure.data.jdbc;
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 JdbcRepositoriesAutoConfigureRegistrar
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 class EnableJdbcRepositoriesConfiguration {
}
}

@ -0,0 +1,20 @@
/*
* Copyright 2012-2018 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
*
* http://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.autoconfigure.data.jdbc;

@ -156,6 +156,12 @@
"description": "Whether to enable Elasticsearch repositories.", "description": "Whether to enable Elasticsearch repositories.",
"defaultValue": true "defaultValue": true
}, },
{
"name": "spring.data.jdbc.repositories.enabled",
"type": "java.lang.Boolean",
"description": "Whether to enable JDBC repositories.",
"defaultValue": true
},
{ {
"name": "spring.data.jpa.repositories.bootstrap-mode", "name": "spring.data.jpa.repositories.bootstrap-mode",
"type": "org.springframework.data.repository.config.BootstrapMode", "type": "org.springframework.data.repository.config.BootstrapMode",

@ -44,6 +44,7 @@ org.springframework.boot.autoconfigure.data.couchbase.CouchbaseRepositoriesAutoC
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchAutoConfiguration,\ org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration,\ org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchRepositoriesAutoConfiguration,\ org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.jdbc.JdbcRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration,\ org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.ldap.LdapRepositoriesAutoConfiguration,\ org.springframework.boot.autoconfigure.data.ldap.LdapRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration,\ org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration,\

@ -0,0 +1,138 @@
/*
* Copyright 2012-2018 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
*
* http://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.autoconfigure.data.jdbc;
import javax.sql.DataSource;
import org.junit.Test;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage;
import org.springframework.boot.autoconfigure.data.empty.EmptyDataPackage;
import org.springframework.boot.autoconfigure.data.jdbc.city.City;
import org.springframework.boot.autoconfigure.data.jdbc.city.CityRepository;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration;
import org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jdbc.repository.config.EnableJdbcRepositories;
import org.springframework.data.jdbc.repository.config.JdbcConfiguration;
import org.springframework.data.jdbc.repository.config.JdbcRepositoryConfigExtension;
import org.springframework.data.repository.Repository;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link JdbcRepositoriesAutoConfiguration}.
*
* @author Andy Wilkinson
*/
public class JdbcRepositoriesAutoConfigurationTests {
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
.withConfiguration(
AutoConfigurations.of(JdbcRepositoriesAutoConfiguration.class));
@Test
public void backsOffWithNoDataSource() {
this.contextRunner.withUserConfiguration(TestConfiguration.class)
.run((context) -> {
assertThat(context)
.doesNotHaveBean(JdbcRepositoryConfigExtension.class);
});
}
@Test
public void backsOffWithNoJdbcOperations() {
this.contextRunner.withUserConfiguration(EmbeddedDataSourceConfiguration.class,
TestConfiguration.class).run((context) -> {
assertThat(context).hasSingleBean(DataSource.class);
assertThat(context)
.doesNotHaveBean(JdbcRepositoryConfigExtension.class);
});
}
@Test
public void basicAutoConfiguration() {
this.contextRunner
.withConfiguration(
AutoConfigurations.of(JdbcTemplateAutoConfiguration.class,
DataSourceAutoConfiguration.class))
.withUserConfiguration(TestConfiguration.class,
EmbeddedDataSourceConfiguration.class)
.withPropertyValues(
"spring.datasource.schema=classpath:data-jdbc-schema.sql",
"spring.datasource.data=classpath:city.sql")
.run((context) -> {
assertThat(context).hasSingleBean(JdbcConfiguration.class);
assertThat(context).hasSingleBean(CityRepository.class);
assertThat(context.getBean(CityRepository.class).findById(2000L))
.isPresent();
});
}
@Test
public void autoConfigurationWithNoRepositories() {
this.contextRunner
.withConfiguration(
AutoConfigurations.of(JdbcTemplateAutoConfiguration.class))
.withUserConfiguration(EmbeddedDataSourceConfiguration.class,
EmptyConfiguration.class)
.run((context) -> {
assertThat(context).hasSingleBean(JdbcConfiguration.class);
assertThat(context).doesNotHaveBean(Repository.class);
});
}
@Test
public void honoursUsersEnableJdbcRepositoriesConfiguration() {
this.contextRunner
.withConfiguration(
AutoConfigurations.of(JdbcTemplateAutoConfiguration.class,
DataSourceAutoConfiguration.class))
.withUserConfiguration(EnableRepositoriesConfiguration.class,
EmbeddedDataSourceConfiguration.class)
.withPropertyValues(
"spring.datasource.schema=classpath:data-jdbc-schema.sql",
"spring.datasource.data=classpath:city.sql")
.run((context) -> {
assertThat(context).hasSingleBean(JdbcConfiguration.class);
assertThat(context).hasSingleBean(CityRepository.class);
assertThat(context.getBean(CityRepository.class).findById(2000L))
.isPresent();
});
}
@TestAutoConfigurationPackage(City.class)
private static class TestConfiguration {
}
@Configuration
@TestAutoConfigurationPackage(EmptyDataPackage.class)
protected static class EmptyConfiguration {
}
@TestAutoConfigurationPackage(EmptyDataPackage.class)
@EnableJdbcRepositories(basePackageClasses = City.class)
private static class EnableRepositoriesConfiguration {
}
}

@ -0,0 +1,63 @@
/*
* Copyright 2012-2018 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
*
* http://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.autoconfigure.data.jdbc.city;
import org.springframework.data.annotation.Id;
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();
}
}

@ -0,0 +1,28 @@
/*
* Copyright 2012-2018 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
*
* http://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.autoconfigure.data.jdbc.city;
import org.springframework.data.repository.CrudRepository;
/**
* Data JDBC repository for working with {@link City Cities}.
*
* @author Andy Wilkinson
*/
public interface CityRepository extends CrudRepository<City, Long> {
}

@ -0,0 +1,7 @@
CREATE TABLE CITY (
id INTEGER IDENTITY PRIMARY KEY,
name VARCHAR(30),
state VARCHAR(30),
country VARCHAR(30),
map VARCHAR(30)
);

@ -355,6 +355,11 @@
<artifactId>spring-boot-starter-data-elasticsearch</artifactId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
<version>${revision}</version> <version>${revision}</version>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
<version>${revision}</version>
</dependency>
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId> <artifactId>spring-boot-starter-data-jpa</artifactId>

@ -659,6 +659,9 @@ content into your application. Rather, pick only the properties that you need.
spring.data.elasticsearch.properties.*= # Additional properties used to configure the client. spring.data.elasticsearch.properties.*= # Additional properties used to configure the client.
spring.data.elasticsearch.repositories.enabled=true # Whether to enable Elasticsearch repositories. spring.data.elasticsearch.repositories.enabled=true # Whether to enable Elasticsearch repositories.
# DATA JDBC
spring.data.jdbc.repositories.enabled=true # Whether to enable JDBC repositories.
# DATA LDAP # DATA LDAP
spring.data.ldap.repositories.enabled=true # Whether to enable LDAP repositories. spring.data.ldap.repositories.enabled=true # Whether to enable LDAP repositories.

@ -3671,7 +3671,7 @@ scenes. If more than one `JdbcTemplate` is defined and no primary candidate exis
[[boot-features-jpa-and-spring-data]] [[boot-features-jpa-and-spring-data]]
=== JPA and "`Spring Data`" === JPA and Spring Data JPA
The Java Persistence API is a standard technology that lets you "`map`" objects to The Java Persistence API is a standard technology that lets you "`map`" objects to
relational databases. The `spring-boot-starter-data-jpa` POM provides a quick way to get relational databases. The `spring-boot-starter-data-jpa` POM provides a quick way to get
started. It provides the following key dependencies: started. It provides the following key dependencies:
@ -3838,6 +3838,23 @@ views. If you do not want this behavior, you should set `spring.jpa.open-in-view
[[boot-features-data-jdbc]]
=== Spring Data JDBC
Spring Data includes repository support for JDBC and will automatically generate SQL for
the methods on `CrudRepository`. For more advanced queries, a `@Query` annotation is
provided.
Spring Boot will auto-configure Spring Data's JDBC repositories when the necessary
dependencies are on the classpath. They can be added to your project with a single
dependency on `spring-boot-starter-data-jdbc`. If necessary, you can take control of
Spring Data JDBC's configuration by adding the `@EnableJdbcRepositories` annotation or a
`JdbcConfiguration` subclass to your application.
TIP: For complete details of Spring Data JDBC, please refer to the
https://projects.spring.io/spring-data-jdbc/[reference documentation].
[[boot-features-sql-h2-console]] [[boot-features-sql-h2-console]]
=== Using H2's Web Console === Using H2's Web Console
The http://www.h2database.com[H2 database] provides a The http://www.h2database.com[H2 database] provides a
@ -7106,8 +7123,9 @@ following example:
[[boot-features-testing-spring-boot-applications-testing-autoconfigured-jdbc-test]] [[boot-features-testing-spring-boot-applications-testing-autoconfigured-jdbc-test]]
==== Auto-configured JDBC Tests ==== Auto-configured JDBC Tests
`@JdbcTest` is similar to `@DataJpaTest` but is for tests that only require a `@JdbcTest` is similar to `@DataJpaTest` but is for tests that only require a
`DataSource`. By default, it configures an in-memory embedded database and a `DataSource` and do not use Spring Data JDBC. By default, it configures an in-memory
`JdbcTemplate`. Regular `@Component` beans are not loaded into the `ApplicationContext`. embedded database and a `JdbcTemplate`. Regular `@Component` beans are not loaded into
the `ApplicationContext`.
TIP: A list of the auto-configurations that are enabled by `@JdbcTest` can be TIP: A list of the auto-configurations that are enabled by `@JdbcTest` can be
<<appendix-test-auto-configuration#test-auto-configuration,found in the appendix>>. <<appendix-test-auto-configuration#test-auto-configuration,found in the appendix>>.
@ -7141,6 +7159,29 @@ If you prefer your test to run against a real database, you can use the
[[boot-features-testing-spring-boot-applications-testing-autoconfigured-jdbc-test]]
==== Auto-configured Data JDBC Tests
`@DataJdbcTest` is similar to `@JdbcTest` but is for tests that use Spring Data JDBC
repositories. By default, it configures an in-memory embedded database, a `JdbcTemplate`,
and Spring Data JDBD repositories. Regular `@Component` beans are not loaded into
the `ApplicationContext`.
TIP: A list of the auto-configurations that are enabled by `@DataJdbcTest` can be
<<appendix-test-auto-configuration#test-auto-configuration,found in the appendix>>.
By default, Data JDBC tests are transactional and roll back at the end of each test. See
the {spring-reference}testing.html#testcontext-tx-enabling-transactions[relevant section]
in the Spring Framework Reference Documentation for more details. If that is not what you
want, you can disable transaction management for a test or for the whole test class as
<<boot-features-testing-spring-boot-applications-testing-autoconfigured-jdbc-test,shown
in the JDBC example>>.
If you prefer your test to run against a real database, you can use the
`@AutoConfigureTestDatabase` annotation in the same way as for `DataJpaTest`. (See
"<<boot-features-testing-spring-boot-applications-testing-autoconfigured-jpa-test>>".)
[[boot-features-testing-spring-boot-applications-testing-autoconfigured-jooq-test]] [[boot-features-testing-spring-boot-applications-testing-autoconfigured-jooq-test]]
==== Auto-configured jOOQ Tests ==== Auto-configured jOOQ Tests
You can use `@JooqTest` in a similar fashion as `@JdbcTest` but for jOOQ-related tests. You can use `@JooqTest` in a similar fashion as `@JdbcTest` but for jOOQ-related tests.

@ -30,6 +30,7 @@
<module>spring-boot-starter-data-couchbase</module> <module>spring-boot-starter-data-couchbase</module>
<module>spring-boot-starter-data-couchbase-reactive</module> <module>spring-boot-starter-data-couchbase-reactive</module>
<module>spring-boot-starter-data-elasticsearch</module> <module>spring-boot-starter-data-elasticsearch</module>
<module>spring-boot-starter-data-jdbc</module>
<module>spring-boot-starter-data-jpa</module> <module>spring-boot-starter-data-jpa</module>
<module>spring-boot-starter-data-ldap</module> <module>spring-boot-starter-data-ldap</module>
<module>spring-boot-starter-data-mongodb</module> <module>spring-boot-starter-data-mongodb</module>

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starters</artifactId>
<version>${revision}</version>
</parent>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
<name>Spring Boot Data JDBC Starter</name>
<description>Starter for using Spring Data JDBC</description>
<properties>
<main.basedir>${basedir}/../../..</main.basedir>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jdbc</artifactId>
</dependency>
</dependencies>
</project>

@ -116,6 +116,11 @@
<artifactId>spring-webflux</artifactId> <artifactId>spring-webflux</artifactId>
<optional>true</optional> <optional>true</optional>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jdbc</artifactId>
<optional>true</optional>
</dependency>
<dependency> <dependency>
<groupId>org.springframework.data</groupId> <groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId> <artifactId>spring-data-jpa</artifactId>

@ -0,0 +1,44 @@
/*
* Copyright 2012-2018 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
*
* http://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.test.autoconfigure.data.jdbc;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
/**
* {@link ImportAutoConfiguration Auto-configuration imports} for typical Data JDBC tests.
* Most tests should consider using {@link DataJdbcTest @DataJdbcTest} rather than using
* this annotation directly.
*
* @author Andy Wilkinson
* @since 2.1.0
* @see DataJdbcTest
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@ImportAutoConfiguration
public @interface AutoConfigureDataJdbc {
}

@ -0,0 +1,103 @@
/*
* Copyright 2012-2018 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
*
* http://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.test.autoconfigure.data.jdbc;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.test.autoconfigure.OverrideAutoConfiguration;
import org.springframework.boot.test.autoconfigure.core.AutoConfigureCache;
import org.springframework.boot.test.autoconfigure.filter.TypeExcludeFilters;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.core.annotation.AliasFor;
import org.springframework.core.env.Environment;
import org.springframework.test.context.BootstrapWith;
import org.springframework.test.context.junit.jupiter.SpringExtension;
/**
* Annotation that can be used in combination with {@code @RunWith(SpringRunner.class)}
* for a typical Data JDBC test. Can be used when a test focuses <strong>only</strong> on
* Data JDBC components.
* <p>
* Using this annotation will disable full auto-configuration and instead apply only
* configuration relevant to Data JDBC tests.
*
* @author Andy Wilkinson
* @since 2.1.0
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@BootstrapWith(DataJdbcTestContextBootstrapper.class)
@ExtendWith(SpringExtension.class)
@OverrideAutoConfiguration(enabled = false)
@TypeExcludeFilters(DataJdbcTypeExcludeFilter.class)
@AutoConfigureCache
@AutoConfigureDataJdbc
@AutoConfigureTestDatabase
@ImportAutoConfiguration
public @interface DataJdbcTest {
/**
* Properties in form {@literal key=value} that should be added to the Spring
* {@link Environment} before the test runs.
* @return the properties to add
*/
String[] properties() default {};
/**
* Determines if default filtering should be used with
* {@link SpringBootApplication @SpringBootApplication}. By default no beans are
* included.
* @see #includeFilters()
* @see #excludeFilters()
* @return if default filters should be used
*/
boolean useDefaultFilters() default true;
/**
* A set of include filters which can be used to add otherwise filtered beans to the
* application context.
* @return include filters to apply
*/
Filter[] includeFilters() default {};
/**
* A set of exclude filters which can be used to filter beans that would otherwise be
* added to the application context.
* @return exclude filters to apply
*/
Filter[] excludeFilters() default {};
/**
* Auto-configuration exclusions that should be applied for this test.
* @return auto-configuration exclusions to apply
*/
@AliasFor(annotation = ImportAutoConfiguration.class, attribute = "exclude")
Class<?>[] excludeAutoConfiguration() default {};
}

@ -0,0 +1,37 @@
/*
* Copyright 2012-2018 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
*
* http://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.test.autoconfigure.data.jdbc;
import org.springframework.boot.test.context.SpringBootTestContextBootstrapper;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.test.context.TestContextBootstrapper;
/**
* {@link TestContextBootstrapper} for {@link DataJdbcTest @DataJdbcTest} support.
*
* @author Andy Wilkinson
*/
class DataJdbcTestContextBootstrapper extends SpringBootTestContextBootstrapper {
@Override
protected String[] getProperties(Class<?> testClass) {
DataJdbcTest annotation = AnnotatedElementUtils.getMergedAnnotation(testClass,
DataJdbcTest.class);
return (annotation != null) ? annotation.properties() : null;
}
}

@ -0,0 +1,73 @@
/*
* Copyright 2012-2018 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
*
* http://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.test.autoconfigure.data.jdbc;
import java.util.Collections;
import java.util.Set;
import org.springframework.boot.context.TypeExcludeFilter;
import org.springframework.boot.test.autoconfigure.filter.AnnotationCustomizableTypeExcludeFilter;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.core.annotation.AnnotatedElementUtils;
/**
* {@link TypeExcludeFilter} for {@link DataJdbcTest @DataJdbcTest}.
*
* @author Andy Wilkinson
*/
class DataJdbcTypeExcludeFilter extends AnnotationCustomizableTypeExcludeFilter {
private final DataJdbcTest annotation;
DataJdbcTypeExcludeFilter(Class<?> testClass) {
this.annotation = AnnotatedElementUtils.getMergedAnnotation(testClass,
DataJdbcTest.class);
}
@Override
protected boolean hasAnnotation() {
return this.annotation != null;
}
@Override
protected Filter[] getFilters(FilterType type) {
switch (type) {
case INCLUDE:
return this.annotation.includeFilters();
case EXCLUDE:
return this.annotation.excludeFilters();
default:
throw new IllegalStateException("Unsupported type " + type);
}
}
@Override
protected boolean isUseDefaultFilters() {
return this.annotation.useDefaultFilters();
}
@Override
protected Set<Class<?>> getDefaultIncludes() {
return Collections.emptySet();
}
@Override
protected Set<Class<?>> getComponentIncludes() {
return Collections.emptySet();
}
}

@ -0,0 +1,20 @@
/*
* Copyright 2012-2018 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
*
* http://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 Data JDBC tests.
*/
package org.springframework.boot.test.autoconfigure.data.jdbc;

@ -2,6 +2,16 @@
org.springframework.boot.test.autoconfigure.core.AutoConfigureCache=\ org.springframework.boot.test.autoconfigure.core.AutoConfigureCache=\
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration
# AutoConfigureDataJdbc auto-configuration imports
org.springframework.boot.test.autoconfigure.data.jdbc.AutoConfigureDataJdbc=\
org.springframework.boot.autoconfigure.data.jdbc.JdbcRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration,\
org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration
# AutoConfigureDataJpa auto-configuration imports # AutoConfigureDataJpa auto-configuration imports
org.springframework.boot.test.autoconfigure.orm.jpa.AutoConfigureDataJpa=\ org.springframework.boot.test.autoconfigure.orm.jpa.AutoConfigureDataJpa=\
org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration,\ org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration,\

@ -0,0 +1,97 @@
/*
* Copyright 2012-2018 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
*
* http://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.test.autoconfigure.data.jdbc;
import javax.sql.DataSource;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration;
import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration;
import org.springframework.context.ApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringRunner;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.boot.test.autoconfigure.AutoConfigurationImportedCondition.importedAutoConfiguration;
/**
* Integration tests for {@link DataJdbcTest}.
*
* @author Andy Wilkinson
*/
@RunWith(SpringRunner.class)
@DataJdbcTest
@TestPropertySource(properties = "spring.datasource.schema=classpath:org/springframework/boot/test/autoconfigure/data/jdbc/schema.sql")
public class DataJdbcTestIntegrationTests {
@Rule
public ExpectedException thrown = ExpectedException.none();
@Autowired
private ExampleRepository repository;
@Autowired
private DataSource dataSource;
@Autowired
private ApplicationContext applicationContext;
@Autowired
private JdbcTemplate jdbcTemplate;
@Test
public void testRepository() {
this.jdbcTemplate.update(
"INSERT INTO EXAMPLE_ENTITY (id, name, reference) VALUES (1, 'a', 'alpha')");
this.jdbcTemplate.update(
"INSERT INTO EXAMPLE_ENTITY (id, name, reference) VALUES (2, 'b', 'bravo')");
assertThat(this.repository.findAll()).hasSize(2);
}
@Test
public void replacesDefinedDataSourceWithEmbeddedDefault() throws Exception {
String product = this.dataSource.getConnection().getMetaData()
.getDatabaseProductName();
assertThat(product).isEqualTo("H2");
}
@Test
public void didNotInjectExampleComponent() {
this.thrown.expect(NoSuchBeanDefinitionException.class);
this.applicationContext.getBean(ExampleComponent.class);
}
@Test
public void flywayAutoConfigurationWasImported() {
assertThat(this.applicationContext)
.has(importedAutoConfiguration(FlywayAutoConfiguration.class));
}
@Test
public void liquibaseAutoConfigurationWasImported() {
assertThat(this.applicationContext)
.has(importedAutoConfiguration(LiquibaseAutoConfiguration.class));
}
}

@ -0,0 +1,46 @@
/*
* Copyright 2012-2018 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
*
* http://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.test.autoconfigure.data.jdbc;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.test.context.junit4.SpringRunner;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for the {@link DataJdbcTest#properties properties} attribute of
* {@link DataJdbcTest @DataJdbcTest}.
*
* @author Andy Wilkinson
*/
@RunWith(SpringRunner.class)
@DataJdbcTest(properties = "spring.profiles.active=test")
public class DataJdbcTestPropertiesIntegrationTests {
@Autowired
private Environment environment;
@Test
public void environmentWithNewProfile() {
assertThat(this.environment.getActiveProfiles()).containsExactly("test");
}
}

@ -0,0 +1,29 @@
/*
* Copyright 2012-2018 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
*
* http://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.test.autoconfigure.data.jdbc;
import org.springframework.stereotype.Component;
/**
* Example component used with {@link DataJdbcTest} tests.
*
* @author Andy Wilkinson
*/
@Component
public class ExampleComponent {
}

@ -0,0 +1,41 @@
/*
* Copyright 2012-2018 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
*
* http://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.test.autoconfigure.data.jdbc;
import javax.sql.DataSource;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
/**
* Example {@link SpringBootApplication} used with {@link DataJdbcTest} tests.
*
* @author Andy Wilkinson
*/
@SpringBootApplication
public class ExampleDataJdbcApplication {
@Bean
public DataSource dataSource() {
EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder()
.generateUniqueName(true).setType(EmbeddedDatabaseType.HSQL);
return builder.build();
}
}

@ -0,0 +1,48 @@
/*
* Copyright 2012-2018 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
*
* http://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.test.autoconfigure.data.jdbc;
import org.springframework.data.annotation.Id;
/**
* Example entity used with {@link DataJdbcTest} tests.
*
* @author Andy Wilkinson
*/
public class ExampleEntity {
@Id
private Long id;
private String name;
private String reference;
public ExampleEntity(String name, String reference) {
this.name = name;
this.reference = reference;
}
public String getName() {
return this.name;
}
public String getReference() {
return this.reference;
}
}

@ -0,0 +1,28 @@
/*
* Copyright 2012-2018 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
*
* http://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.test.autoconfigure.data.jdbc;
import org.springframework.data.repository.CrudRepository;
/**
* Example repository used with {@link DataJdbcTest} tests.
*
* @author Andy Wilkinson
*/
public interface ExampleRepository extends CrudRepository<ExampleEntity, Long> {
}

@ -50,6 +50,9 @@ The following sample applications are provided:
| link:spring-boot-sample-data-elasticsearch[spring-boot-sample-data-elasticsearch] | link:spring-boot-sample-data-elasticsearch[spring-boot-sample-data-elasticsearch]
| Stores data using Spring Data Elasticsearch | Stores data using Spring Data Elasticsearch
| link:spring-boot-sample-data-jdbc[spring-boot-sample-data-jdbc]
| Stores data using Spring Data JDBC
| link:spring-boot-sample-data-jpa[spring-boot-sample-data-jpa] | link:spring-boot-sample-data-jpa[spring-boot-sample-data-jpa]
| Stores data using Spring Data JPA with Hibernate | Stores data using Spring Data JPA with Hibernate

@ -35,6 +35,7 @@
<module>spring-boot-sample-data-cassandra</module> <module>spring-boot-sample-data-cassandra</module>
<module>spring-boot-sample-data-couchbase</module> <module>spring-boot-sample-data-couchbase</module>
<module>spring-boot-sample-data-elasticsearch</module> <module>spring-boot-sample-data-elasticsearch</module>
<module>spring-boot-sample-data-jdbc</module>
<module>spring-boot-sample-data-jpa</module> <module>spring-boot-sample-data-jpa</module>
<module>spring-boot-sample-data-ldap</module> <module>spring-boot-sample-data-ldap</module>
<module>spring-boot-sample-data-mongodb</module> <module>spring-boot-sample-data-mongodb</module>

@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<!-- Your own application should inherit from spring-boot-starter-parent -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-samples</artifactId>
<version>${revision}</version>
</parent>
<artifactId>spring-boot-sample-data-jdbc</artifactId>
<name>Spring Boot Data JDBC Sample</name>
<description>Spring Boot Data JDBC Sample</description>
<properties>
<main.basedir>${basedir}/../..</main.basedir>
</properties>
<dependencies>
<!-- Compile -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Runtime -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<!-- Test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

@ -0,0 +1,56 @@
/*
* Copyright 2012-2018 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
*
* http://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 sample.data.jdbc;
import java.time.LocalDate;
import org.springframework.data.annotation.Id;
class Customer {
@Id
private Long id;
private String firstName;
private LocalDate dateOfBirth;
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
public String getFirstName() {
return this.firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public LocalDate getDateOfBirth() {
return this.dateOfBirth;
}
public void setDateOfBirth(LocalDate dateOfBirth) {
this.dateOfBirth = dateOfBirth;
}
}

@ -0,0 +1,30 @@
/*
* Copyright 2012-2018 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
*
* http://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 sample.data.jdbc;
import java.util.List;
import org.springframework.data.jdbc.repository.query.Query;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.query.Param;
interface CustomerRepository extends CrudRepository<Customer, Long> {
@Query("select id, first_name, date_of_birth from customer where upper(first_name) like '%' || upper(:name) || '%' ")
List<Customer> findByName(@Param("name") String name);
}

@ -0,0 +1,43 @@
/*
* Copyright 2012-2018 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
*
* http://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 sample.data.jdbc;
import java.util.List;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class SampleController {
private final CustomerRepository customerRepository;
public SampleController(CustomerRepository customerRepository) {
this.customerRepository = customerRepository;
}
@GetMapping("/")
@ResponseBody
@Transactional(readOnly = true)
public List<Customer> customers(@RequestParam String name) {
return this.customerRepository.findByName(name);
}
}

@ -0,0 +1,29 @@
/*
* Copyright 2012-2018 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
*
* http://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 sample.data.jdbc;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SampleDataJdbcApplication {
public static void main(String[] args) {
SpringApplication.run(SampleDataJdbcApplication.class);
}
}

@ -0,0 +1,2 @@
INSERT INTO CUSTOMER (ID, FIRST_NAME, DATE_OF_BIRTH) values (1, 'Meredith', '1998-07-13');
INSERT INTO CUSTOMER (ID, FIRST_NAME, DATE_OF_BIRTH) values (2, 'Joan', '1982-10-29');

@ -0,0 +1,5 @@
CREATE TABLE CUSTOMER (
ID INTEGER IDENTITY PRIMARY KEY,
FIRST_NAME VARCHAR(30),
DATE_OF_BIRTH DATE
);

@ -0,0 +1,56 @@
/*
* Copyright 2012-2018 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
*
* http://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 sample.data.jdbc;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Integration tests for {@link CustomerRepository}.
*
* @author Andy Wilkinson
*/
@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureTestDatabase
public class CustomerRepositoryIntegrationTests {
@Autowired
private CustomerRepository repository;
@Test
public void findAllCustomers() {
assertThat(this.repository.findAll()).hasSize(2);
}
@Test
public void findByNameWithMatch() {
assertThat(this.repository.findByName("joan")).hasSize(1);
}
@Test
public void findByNameWithNoMatch() {
assertThat(this.repository.findByName("hugh")).isEmpty();
}
}

@ -0,0 +1,60 @@
/*
* Copyright 2012-2018 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
*
* http://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 sample.data.jdbc;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import static org.hamcrest.Matchers.containsString;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* Integration tests for {@link SampleDataJdbcApplication}.
*
* @author Andy Wilkinson
*/
@RunWith(SpringRunner.class)
@SpringBootTest
public class SampleDataJdbcApplicationTests {
@Autowired
private WebApplicationContext context;
private MockMvc mvc;
@Before
public void setUp() {
this.mvc = MockMvcBuilders.webAppContextSetup(this.context).build();
}
@Test
public void testCustomers() throws Exception {
this.mvc.perform(get("/").param("name", "merEDith")).andExpect(status().isOk())
.andExpect(content().string(containsString("Meredith")));
}
}
Loading…
Cancel
Save