diff --git a/README.adoc b/README.adoc index 31d15d4..1c32284 100644 --- a/README.adoc +++ b/README.adoc @@ -1,88 +1,196 @@ -image:https://spring.io/badges/spring-data-jdbc/ga.svg["Spring Data JDBC", link="https://spring.io/projects/spring-data-jdbc#learn"] -image:https://spring.io/badges/spring-data-jdbc/snapshot.svg["Spring Data JDBC", link="https://spring.io/projects/spring-data-jdbc#learn"] += Spring Data R2DBC -= Spring Data JDBC +The primary goal of the http://projects.spring.io/spring-data[Spring Data] project is to make it easier to build Spring-powered applications that use data access technologies. *Spring Data R2DBC* offers the popular Repository abstraction based on https://r2dbc.io[R2DBC]. -The primary goal of the http://projects.spring.io/spring-data[Spring Data] project is to make it easier to build Spring-powered applications that use data access technologies. *Spring Data JDBC* offers the popular Repository abstraction based on JDBC. +R2DBC is the abbreviation for https://github.com/r2dbc/[Reactive Relational Database Connectivity], an incubator to integrate relational databases using a reactive driver. -It aims at being conceptually easy. -In order to achieve this it does NOT offer caching, lazy loading, write behind or many other features of JPA. -This makes Spring Data JDBC a simple, limited, opinionated ORM. +The state of R2DBC is incubating to evaluate how an reactive integration could look like. To get started, you need a R2DBC driver first. -== Features +== This is NOT an ORM -* Implementation of CRUD methods for Aggregates. -* `@Query` annotation -* Support for transparent auditing (created, last changed) -* Events for persistence events -* Possibility to integrate custom repository code -* JavaConfig based repository configuration by introducing `EnableJdbcRepository` -* Integration with MyBatis +Spring Data R2DBC does not try to be an ORM. +Instead it is more of a construction kit for your personal reactive relational data access component that you can define the way you like or need it. -== Getting Help +== Maven Coordinates -If you are new to Spring Data JDBC read the following two articles https://spring.io/blog/2018/09/17/introducing-spring-data-jdbc["Introducing Spring Data JDBC"] and https://spring.io/blog/2018/09/24/spring-data-jdbc-references-and-aggregates["Spring Data JDBC, References, and Aggregates"] - -There are also examples in the https://github.com/spring-projects/spring-data-examples/tree/master/jdbc[Spring Data Examples] project. - -A very good source of information is the source code in this repository. -Especially the integration tests (if you are reading this on github, type `t` and then `IntegrationTests.java`) - -We are keeping an eye on the (soon to be created) https://stackoverflow.com/questions/tagged/spring-data-jdbc[spring-data-jdbc tag on stackoverflow]. - -If you think you found a bug, or have a feature request please https://jira.spring.io/browse/DATAJDBC/?selectedTab=com.atlassian.jira.jira-projects-plugin:summary-panel[create a ticket in our issue tracker]. - -== Execute Tests - -=== Fast running tests - -Fast running tests can be executed with a simple - -[source] +[source,xml] ---- -mvn test + + org.springframework.data + spring-data-r2dbc + 1.0.0.BUILD-SNAPSHOT + ---- -This will execute unit tests and integration tests using an in-memory database. -=== Running tests with a real database +== DatabaseClient -In order to run the integration tests against a specific database you need to have a local Docker installation available, and then execute. +All functionality is encapsulated in `DatabaseClient` which is the entry point for applications that wish to integrate with relational databases using reactive drivers: -[source] +[source,java] ---- -mvn test -Dspring.profiles.active= +PostgresqlConnectionFactory connectionFactory = new PostgresqlConnectionFactory(PostgresqlConnectionConfiguration.builder() + .host(…) + .database(…) + .username(…) + .password(…).build()); + +DatabaseClient databaseClient = DatabaseClient.create(connectionFactory); ---- -This will also execute the unit tests. +The client API provides covers the following features: -Currently the following _databasetypes_ are available: +* Execution of generic SQL and consumption of update count/row results. +* Generic `SELECT` with paging and ordering. +* `SELECT` of mapped objects with paging and ordering. +* Generic `INSERT` with parameter binding. +* `INSERT` of mapped objects. +* Parameter binding using the native syntax. +* Result consumption: Update count, unmapped (`Map`), mapped to entities, extraction function. +* Reactive repositories using `@Query` annotated methods. +* Transaction Management. -* hsql (default, does not require a running database) -* mysql -* postgres -* mariadb +=== Examples executing generic SQL statements -=== Run tests with all databases - -[source] +[source,java] ---- -mvn test -Pall-dbs +Mono count = databaseClient.execute() + .sql("INSERT INTO legoset (id, name, manual) VALUES($1, $2, $3)") + .bind("$1", 42055) + .bind("$2", "Description") + .bindNull("$3", Integer.class) + .fetch() + .rowsUpdated(); + +Flux> rows = databaseClient.execute() + .sql("SELECT id, name, manual FROM legoset") + .fetch().all(); + +Flux result = db.execute() + .sql("SELECT txid_current();") + .exchange() + .flatMapMany(it -> it.extract((r, md) -> r.get(0, Long.class)).all()); ---- -This will execute the unit tests, and all the integration tests with all the databases we currently support for testing. Running the integration-tests depends on Docker. +=== Examples selecting data -== Contributing to Spring Data JDBC +[source,java] +---- + +Flux> rows = databaseClient.select() + .from("legoset") + .orderBy(Sort.by(desc("id"))) + .fetch() + .all(); + +Flux rows = databaseClient.select() + .from("legoset") + .orderBy(Sort.by(desc("id"))) + .as(LegoSet.class) + .fetch() + .all(); +---- + +=== Examples inserting data + +[source,java] +---- +Flux ids = databaseClient.insert() + .into("legoset") + .value("id", 42055) + .value("name", "Description") + .nullValue("manual", Integer.class) + .exchange() // + .flatMapMany(it -> it.extract((r, m) -> r.get("id", Integer.class)).all()) + +Flux ids = databaseClient.insert() + .into(LegoSet.class) + .using(legoSet) + .exchange() + .flatMapMany(it -> it.extract((r, m) -> r.get("id", Integer.class)).all()) +---- + +=== Examples using reactive repositories + +[source,java] +---- +interface LegoSetRepository extends ReactiveCrudRepository { + + @Query("SELECT * FROM legoset WHERE name like $1") + Flux findByNameContains(String name); + + @Query("SELECT * FROM legoset WHERE manual = $1") + Mono findByManual(int manual); +} +---- + +=== Examples using transaction control + +All examples above run with auto-committed transactions. To get group multiple statements within the same transaction or +control the transaction yourself, you need to use `TransactionalDatabaseClient`: + +[source,java] +---- +TransactionalDatabaseClient databaseClient = TransactionalDatabaseClient.create(connectionFactory); +---- + +`TransactionalDatabaseClient` allows multiple flavors of transaction management: + +* Participate in ongoing transactions and fall-back to auto-commit mode if there's no active transaction (default). +* Group multiple statements in a managed transaction using `TransactionalDatabaseClient.inTransaction(…)`. +* Application-controlled transaction management using `TransactionalDatabaseClient.beginTransaction()`/`commitTransaction()`/`rollbackTransaction()`. + +Participating in ongoing transactions does not require changes to your application code. Instead, a managed transaction must be hosted by your application container. Transaction control needs to happen there, as well. + +**Statement grouping** + +[source,java] +---- +Flux rowsUpdated = databaseClient.inTransaction(db -> { + + return db.execute().sql("INSERT INTO legoset (id, name, manual) VALUES($1, $2, $3)") // + .bind(0, 42055) // + .bind(1, "Description") // + .bindNull("$3", Integer.class) // + .fetch() + .rowsUpdated(); +}); +---- + +**Application-controlled transaction management** + +[source,java] +---- +Flux txId = databaseClient.execute().sql("SELECT txid_current();").exchange() + .flatMapMany(it -> it.extract((r, md) -> r.get(0, Long.class)).all()); + +Mono then = databaseClient.enableTransactionSynchronization(databaseClient.beginTransaction() // + .thenMany(txId)) // + .then(databaseClient.rollbackTransaction())); +---- + +NOTE: Application-controlled transactions must be enabled with `enableTransactionSynchronization(…)`. + +== Building from Source + +You don't need to build from source to use Spring Data R2DBC (binaries in https://repo.spring.io[repo.spring.io]), but if you want to try out the latest and greatest, Spring Data R2DBC can be easily built with the https://github.com/takari/maven-wrapper[maven wrapper]. You also need JDK 1.8. + +[indent=0] +---- + $ ./mvnw clean install +---- + +If you want to build with the regular `mvn` command, you will need https://maven.apache.org/run-maven/index.html[Maven v3.5.0 or above]. + +_Also see link:CONTRIBUTING.adoc[CONTRIBUTING.adoc] if you wish to submit pull requests, and in particular please fill out the https://cla.pivotal.io/[Contributor's Agreement] before your first change._ + +== Contributing to Spring Data R2DBC Here are some ways for you to get involved in the community: -* Get involved with the Spring community by helping out on http://stackoverflow.com/questions/tagged/spring-data-jdbc[stackoverflow] by responding to questions and joining the debate. -* Create https://jira.spring.io/browse/DATAJDBC[JIRA] tickets for bugs and new features and comment and vote on the ones that you are interested in. +* Get involved with the Spring community by helping out on http://stackoverflow.com/questions/tagged/spring-data-r2dbc[Stackoverflow] by responding to questions and joining the debate. +* Create https://github.com/spring-data/spring-data-r2dbc[GitHub] tickets for bugs and new features and comment and vote on the ones that you are interested in. * Github is for social coding: if you want to write code, we encourage contributions through pull requests from http://help.github.com/forking/[forks of this repository]. If you want to contribute code this way, please reference a JIRA ticket as well, covering the specific issue you are addressing. * Watch for upcoming articles on Spring by http://spring.io/blog[subscribing] to spring.io. Before we accept a non-trivial patch or pull request we will need you to https://cla.pivotal.io/sign/spring[sign the Contributor License Agreement]. Signing the contributor’s agreement does not grant anyone commit rights to the main repository, but it does mean that we can accept your contributions, and you will get an author credit if we do. If you forget to do so, you'll be reminded when you submit a pull request. Active contributors might be asked to join the core team, and given the ability to merge pull requests. - -== License - -link:src/main/resources/license.txt[The license und which Spring Data JDBC is published can be found here]. diff --git a/pom.xml b/pom.xml index e187385..73ed136 100644 --- a/pom.xml +++ b/pom.xml @@ -5,12 +5,12 @@ 4.0.0 org.springframework.data - spring-data-jdbc - 1.1.0.r2dbc-SNAPSHOT + spring-data-r2dbc + 1.0.0.BUILD-SNAPSHOT - Spring Data JDBC - Spring Data module for JDBC repositories. - http://projects.spring.io/spring-data-jdbc + Spring Data R2DBC + Spring Data module for R2DBC. + http://projects.spring.io/spring-data-r2dbc org.springframework.data.build @@ -20,33 +20,29 @@ - DATAJDBC + DATAR2DBC 2.2.0.BUILD-SNAPSHOT - spring.data.jdbc + 1.1.0.BUILD-SNAPSHOT + spring.data.r2dbc reuseReports - 3.6.2 0.1.4 2.2.8 - 3.4.6 - 1.3.2 - 5.1.41 42.0.0 - 2.2.3 1.0.0.M5 1.0.0.M5 1.7.3 - 2017 + 2018 - schauder - Jens Schauder - jschauder(at)pivotal.io + mpaluch + Mark Paluch + mpaluch(at)pivotal.io Pivotal Software, Inc. https://pivotal.io @@ -55,15 +51,15 @@ +1 - gregturn - Greg L. Turnquist - gturnquist(at)pivotal.io + ogierke + Oliver Gierke + ogierke(at)pivotal.io Pivotal Software, Inc. https://pivotal.io - Project Contributor + Project Lead - -6 + +1 @@ -177,6 +173,12 @@ ${springdata.commons} + + ${project.groupId} + spring-data-relational + ${springdata.relational} + + org.springframework spring-tx @@ -206,40 +208,17 @@ io.r2dbc r2dbc-spi ${r2dbc-spi.version} - true io.projectreactor reactor-core - true - - - - org.mybatis - mybatis-spring - ${mybatis-spring.version} - true - - - - org.mybatis - mybatis - ${mybatis.version} - true - - - - org.hsqldb - hsqldb - ${hsqldb.version} - test org.assertj assertj-core - ${assertj-core.version} + ${assertj} test @@ -249,13 +228,6 @@ test - - mysql - mysql-connector-java - ${mysql-connector-java.version} - test - - org.postgresql postgresql @@ -263,13 +235,6 @@ test - - org.mariadb.jdbc - mariadb-java-client - ${mariadb-java-client.version} - test - - io.r2dbc r2dbc-postgresql @@ -304,13 +269,6 @@ test - - org.testcontainers - mariadb - ${testcontainers.version} - test - - diff --git a/src/main/java/org/springframework/data/jdbc/repository/config/JdbcRepositoryConfigExtension.java b/src/main/java/org/springframework/data/jdbc/repository/config/JdbcRepositoryConfigExtension.java deleted file mode 100644 index fcac316..0000000 --- a/src/main/java/org/springframework/data/jdbc/repository/config/JdbcRepositoryConfigExtension.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2017-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.data.jdbc.repository.config; - -import java.util.Locale; - -import org.springframework.data.jdbc.repository.support.JdbcRepositoryFactoryBean; -import org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport; -import org.springframework.data.repository.core.RepositoryMetadata; - -/** - * {@link org.springframework.data.repository.config.RepositoryConfigurationExtension} extending the repository - * registration process by registering JDBC repositories. - * - * @author Jens Schauder - * @author Mark Paluch - */ -public class JdbcRepositoryConfigExtension extends RepositoryConfigurationExtensionSupport { - - /* - * (non-Javadoc) - * @see org.springframework.data.repository.config.RepositoryConfigurationExtension#getModuleName() - */ - @Override - public String getModuleName() { - return "JDBC"; - } - - /* - * (non-Javadoc) - * @see org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport#getRepositoryFactoryBeanClassName() - */ - @Override - public String getRepositoryFactoryBeanClassName() { - return JdbcRepositoryFactoryBean.class.getName(); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport#getModulePrefix() - */ - @Override - protected String getModulePrefix() { - return getModuleName().toLowerCase(Locale.US); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport#useRepositoryConfiguration(org.springframework.data.repository.core.RepositoryMetadata) - */ - @Override - protected boolean useRepositoryConfiguration(RepositoryMetadata metadata) { - return !metadata.isReactiveRepository(); - } -} diff --git a/src/main/java/org/springframework/data/r2dbc/function/DatabaseClient.java b/src/main/java/org/springframework/data/r2dbc/function/DatabaseClient.java index e587d07..4e49dcb 100644 --- a/src/main/java/org/springframework/data/r2dbc/function/DatabaseClient.java +++ b/src/main/java/org/springframework/data/r2dbc/function/DatabaseClient.java @@ -315,7 +315,6 @@ public interface DatabaseClient { */ S project(String... selectedFields); - /** * Configure {@link Sort}. * diff --git a/src/main/java/org/springframework/data/r2dbc/function/DefaultSqlResult.java b/src/main/java/org/springframework/data/r2dbc/function/DefaultSqlResult.java index ec38a79..378b473 100644 --- a/src/main/java/org/springframework/data/r2dbc/function/DefaultSqlResult.java +++ b/src/main/java/org/springframework/data/r2dbc/function/DefaultSqlResult.java @@ -48,28 +48,27 @@ class DefaultSqlResult implements SqlResult { this.resultFunction = resultFunction; this.updatedRowsFunction = updatedRowsFunction; - this.fetchSpec = new DefaultFetchSpec<>(connectionAccessor, sql, - new SqlFunction>() { - @Override - public Flux apply(Connection connection) { - return resultFunction.apply(connection).flatMap(result -> result.map(mappingFunction)); - } + this.fetchSpec = new DefaultFetchSpec<>(connectionAccessor, sql, new SqlFunction>() { + @Override + public Flux apply(Connection connection) { + return resultFunction.apply(connection).flatMap(result -> result.map(mappingFunction)); + } - @Override - public String getSql() { - return sql; - } - }, new SqlFunction>() { - @Override - public Mono apply(Connection connection) { - return updatedRowsFunction.apply(connection); - } + @Override + public String getSql() { + return sql; + } + }, new SqlFunction>() { + @Override + public Mono apply(Connection connection) { + return updatedRowsFunction.apply(connection); + } - @Override - public String getSql() { - return sql; - } - }); + @Override + public String getSql() { + return sql; + } + }); } /* (non-Javadoc) diff --git a/src/main/java/org/springframework/data/r2dbc/function/convert/EntityRowMapper.java b/src/main/java/org/springframework/data/r2dbc/function/convert/EntityRowMapper.java index edf84d9..0aa86be 100644 --- a/src/main/java/org/springframework/data/r2dbc/function/convert/EntityRowMapper.java +++ b/src/main/java/org/springframework/data/r2dbc/function/convert/EntityRowMapper.java @@ -155,8 +155,7 @@ public class EntityRowMapper implements BiFunction { String column = prefix + entity.getRequiredPersistentProperty(parameter.getName()).getColumnName(); try { - return conversionService.convert(resultSet.get(column), - parameter.getType().getType()); + return conversionService.convert(resultSet.get(column), parameter.getType().getType()); } catch (Exception o_O) { throw new MappingException(String.format("Couldn't read column %s from Row.", column), o_O); } diff --git a/src/main/java/org/springframework/data/r2dbc/function/convert/MappingR2dbcConverter.java b/src/main/java/org/springframework/data/r2dbc/function/convert/MappingR2dbcConverter.java index b187e67..49fb815 100644 --- a/src/main/java/org/springframework/data/r2dbc/function/convert/MappingR2dbcConverter.java +++ b/src/main/java/org/springframework/data/r2dbc/function/convert/MappingR2dbcConverter.java @@ -109,4 +109,3 @@ public class MappingR2dbcConverter { return relationalConverter.getMappingContext(); } } - diff --git a/src/main/java/org/springframework/data/relational/repository/query/RelationalParameterAccessor.java b/src/main/java/org/springframework/data/r2dbc/repository/query/Query.java similarity index 51% rename from src/main/java/org/springframework/data/relational/repository/query/RelationalParameterAccessor.java rename to src/main/java/org/springframework/data/r2dbc/repository/query/Query.java index 5212356..43b451d 100644 --- a/src/main/java/org/springframework/data/relational/repository/query/RelationalParameterAccessor.java +++ b/src/main/java/org/springframework/data/r2dbc/repository/query/Query.java @@ -13,25 +13,29 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.relational.repository.query; +package org.springframework.data.r2dbc.repository.query; -import org.springframework.data.repository.query.ParameterAccessor; -import org.springframework.data.repository.query.Parameters; +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.springframework.data.annotation.QueryAnnotation; /** - * JDBC-specific {@link ParameterAccessor}. - * + * Annotation to provide SQL statements that will get used for executing the method. + * * @author Mark Paluch */ -public interface RelationalParameterAccessor extends ParameterAccessor { +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +@QueryAnnotation +@Documented +public @interface Query { /** - * Returns the raw parameter values of the underlying query method. + * The SQL statement to execute when the annotated method gets invoked. */ - Object[] getValues(); - - /** - * @return the bindable parameters. - */ - Parameters getBindableParameters(); + String value(); } diff --git a/src/main/java/org/springframework/data/r2dbc/repository/query/R2dbcQueryMethod.java b/src/main/java/org/springframework/data/r2dbc/repository/query/R2dbcQueryMethod.java index 48f7fd5..63adcae 100644 --- a/src/main/java/org/springframework/data/r2dbc/repository/query/R2dbcQueryMethod.java +++ b/src/main/java/org/springframework/data/r2dbc/repository/query/R2dbcQueryMethod.java @@ -26,7 +26,6 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Slice; import org.springframework.data.domain.Sort; -import org.springframework.data.jdbc.repository.query.Query; import org.springframework.data.mapping.context.MappingContext; import org.springframework.data.projection.ProjectionFactory; import org.springframework.data.relational.core.mapping.RelationalPersistentEntity; diff --git a/src/main/java/org/springframework/data/r2dbc/repository/query/StringBasedR2dbcQuery.java b/src/main/java/org/springframework/data/r2dbc/repository/query/StringBasedR2dbcQuery.java index 3ff5291..d3fb559 100644 --- a/src/main/java/org/springframework/data/r2dbc/repository/query/StringBasedR2dbcQuery.java +++ b/src/main/java/org/springframework/data/r2dbc/repository/query/StringBasedR2dbcQuery.java @@ -15,7 +15,6 @@ */ package org.springframework.data.r2dbc.repository.query; -import org.springframework.data.jdbc.repository.query.Query; import org.springframework.data.r2dbc.function.DatabaseClient; import org.springframework.data.r2dbc.function.DatabaseClient.BindSpec; import org.springframework.data.r2dbc.function.convert.MappingR2dbcConverter; diff --git a/src/main/java/org/springframework/data/relational/repository/query/DtoInstantiatingConverter.java b/src/main/java/org/springframework/data/relational/repository/query/DtoInstantiatingConverter.java deleted file mode 100644 index 6299e38..0000000 --- a/src/main/java/org/springframework/data/relational/repository/query/DtoInstantiatingConverter.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright 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.data.relational.repository.query; - -import org.springframework.core.convert.converter.Converter; -import org.springframework.data.convert.EntityInstantiator; -import org.springframework.data.convert.EntityInstantiators; -import org.springframework.data.mapping.PersistentEntity; -import org.springframework.data.mapping.PersistentProperty; -import org.springframework.data.mapping.PersistentPropertyAccessor; -import org.springframework.data.mapping.PreferredConstructor; -import org.springframework.data.mapping.PreferredConstructor.Parameter; -import org.springframework.data.mapping.SimplePropertyHandler; -import org.springframework.data.mapping.context.MappingContext; -import org.springframework.data.mapping.model.ParameterValueProvider; -import org.springframework.data.relational.core.mapping.RelationalPersistentEntity; -import org.springframework.data.relational.core.mapping.RelationalPersistentProperty; -import org.springframework.util.Assert; - -/** - * {@link Converter} to instantiate DTOs from fully equipped domain objects. - * - * @author Mark Paluch - */ -public class DtoInstantiatingConverter implements Converter { - - private final Class targetType; - private final MappingContext, ? extends PersistentProperty> context; - private final EntityInstantiator instantiator; - - /** - * Creates a new {@link Converter} to instantiate DTOs. - * - * @param dtoType must not be {@literal null}. - * @param context must not be {@literal null}. - * @param instantiators must not be {@literal null}. - */ - public DtoInstantiatingConverter(Class dtoType, - MappingContext, ? extends RelationalPersistentProperty> context, - EntityInstantiators instantiator) { - - Assert.notNull(dtoType, "DTO type must not be null!"); - Assert.notNull(context, "MappingContext must not be null!"); - Assert.notNull(instantiator, "EntityInstantiators must not be null!"); - - this.targetType = dtoType; - this.context = context; - this.instantiator = instantiator.getInstantiatorFor(context.getRequiredPersistentEntity(dtoType)); - } - - /* - * (non-Javadoc) - * @see org.springframework.core.convert.converter.Converter#convert(java.lang.Object) - */ - @Override - public Object convert(Object source) { - - if (targetType.isInterface()) { - return source; - } - - final PersistentEntity sourceEntity = context.getRequiredPersistentEntity(source.getClass()); - final PersistentPropertyAccessor sourceAccessor = sourceEntity.getPropertyAccessor(source); - final PersistentEntity targetEntity = context.getRequiredPersistentEntity(targetType); - final PreferredConstructor> constructor = targetEntity - .getPersistenceConstructor(); - - @SuppressWarnings({ "rawtypes", "unchecked" }) - Object dto = instantiator.createInstance(targetEntity, new ParameterValueProvider() { - - @Override - public Object getParameterValue(Parameter parameter) { - return sourceAccessor.getProperty(sourceEntity.getPersistentProperty(parameter.getName())); - } - }); - - final PersistentPropertyAccessor dtoAccessor = targetEntity.getPropertyAccessor(dto); - - targetEntity.doWithProperties(new SimplePropertyHandler() { - - @Override - public void doWithPersistentProperty(PersistentProperty property) { - - if (constructor.isConstructorParameter(property)) { - return; - } - - dtoAccessor.setProperty(property, - sourceAccessor.getProperty(sourceEntity.getPersistentProperty(property.getName()))); - } - }); - - return dto; - } -} diff --git a/src/main/java/org/springframework/data/relational/repository/query/RelationalEntityInformation.java b/src/main/java/org/springframework/data/relational/repository/query/RelationalEntityInformation.java deleted file mode 100644 index c03f202..0000000 --- a/src/main/java/org/springframework/data/relational/repository/query/RelationalEntityInformation.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 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.data.relational.repository.query; - -import org.springframework.data.repository.core.EntityInformation; - -/** - * Relational database-specific {@link EntityInformation}. - * - * @author Mark Paluch - */ -public interface RelationalEntityInformation extends EntityInformation { - - /** - * Returns the name of the table the entity shall be persisted to. - * - * @return - */ - String getTableName(); -} diff --git a/src/main/java/org/springframework/data/relational/repository/query/RelationalEntityMetadata.java b/src/main/java/org/springframework/data/relational/repository/query/RelationalEntityMetadata.java deleted file mode 100644 index 8691cb5..0000000 --- a/src/main/java/org/springframework/data/relational/repository/query/RelationalEntityMetadata.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 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.data.relational.repository.query; - -import org.springframework.data.relational.core.mapping.RelationalPersistentEntity; -import org.springframework.data.repository.core.EntityMetadata; - -/** - * Extension of {@link EntityMetadata} to additionally expose the collection name an entity shall be persisted to. - * - * @author Mark Paluch - */ -public interface RelationalEntityMetadata extends EntityMetadata { - - /** - * Returns the name of the table the entity shall be persisted to. - * - * @return - */ - String getTableName(); - - /** - * Returns the {@link RelationalPersistentEntity} that supposed to determine the table to be queried. - * - * @return - */ - RelationalPersistentEntity getTableEntity(); -} diff --git a/src/main/java/org/springframework/data/relational/repository/query/RelationalParameters.java b/src/main/java/org/springframework/data/relational/repository/query/RelationalParameters.java deleted file mode 100644 index 8af173e..0000000 --- a/src/main/java/org/springframework/data/relational/repository/query/RelationalParameters.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright 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.data.relational.repository.query; - -import java.lang.reflect.Method; -import java.util.List; - -import org.springframework.core.MethodParameter; -import org.springframework.data.relational.repository.query.RelationalParameters.RelationalParameter; -import org.springframework.data.repository.query.Parameter; -import org.springframework.data.repository.query.Parameters; - -/** - * Custom extension of {@link Parameters}. - * - * @author Mark Paluch - */ -public class RelationalParameters extends Parameters { - - /** - * Creates a new {@link RelationalParameters} instance from the given {@link Method}. - * - * @param method must not be {@literal null}. - */ - public RelationalParameters(Method method) { - super(method); - } - - private RelationalParameters(List parameters) { - super(parameters); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.repository.query.Parameters#createParameter(org.springframework.core.MethodParameter) - */ - @Override - protected RelationalParameter createParameter(MethodParameter parameter) { - return new RelationalParameter(parameter); - } - - /* - * (non-Javadoc) - * @see org.springframework.data.repository.query.Parameters#createFrom(java.util.List) - */ - @Override - protected RelationalParameters createFrom(List parameters) { - return new RelationalParameters(parameters); - } - - /** - * Custom {@link Parameter} implementation. - * - * @author Mark Paluch - */ - public static class RelationalParameter extends Parameter { - - /** - * Creates a new {@link RelationalParameter}. - * - * @param parameter must not be {@literal null}. - */ - RelationalParameter(MethodParameter parameter) { - super(parameter); - } - } -} diff --git a/src/main/java/org/springframework/data/relational/repository/query/RelationalParametersParameterAccessor.java b/src/main/java/org/springframework/data/relational/repository/query/RelationalParametersParameterAccessor.java deleted file mode 100644 index c62c7cb..0000000 --- a/src/main/java/org/springframework/data/relational/repository/query/RelationalParametersParameterAccessor.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 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.data.relational.repository.query; - -import java.util.Arrays; -import java.util.List; - -import org.springframework.data.repository.query.Parameters; -import org.springframework.data.repository.query.ParametersParameterAccessor; -import org.springframework.data.repository.query.QueryMethod; - -/** - * JDBC-specific {@link ParametersParameterAccessor}. - * - * @author Mark Paluch - */ -public class RelationalParametersParameterAccessor extends ParametersParameterAccessor - implements RelationalParameterAccessor { - - private final List values; - - /** - * Creates a new {@link RelationalParametersParameterAccessor}. - * - * @param method must not be {@literal null}. - * @param values must not be {@literal null}. - */ - public RelationalParametersParameterAccessor(QueryMethod method, Object[] values) { - - super(method.getParameters(), values); - this.values = Arrays.asList(values); - } - - /* (non-Javadoc) - * @see org.springframework.data.jdbc.repository.query.JdbcParameterAccessor#getValues() - */ - @Override - public Object[] getValues() { - return values.toArray(); - } - - /* (non-Javadoc) - * @see org.springframework.data.jdbc.repository.query.RelationalParameterAccessor#getBindableParameters() - */ - @Override - public Parameters getBindableParameters() { - return getParameters().getBindableParameters(); - } -} diff --git a/src/main/java/org/springframework/data/relational/repository/query/SimpleRelationalEntityMetadata.java b/src/main/java/org/springframework/data/relational/repository/query/SimpleRelationalEntityMetadata.java deleted file mode 100644 index f64c7f5..0000000 --- a/src/main/java/org/springframework/data/relational/repository/query/SimpleRelationalEntityMetadata.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 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.data.relational.repository.query; - -import lombok.Getter; - -import org.springframework.data.relational.core.mapping.RelationalPersistentEntity; -import org.springframework.util.Assert; - -/** - * Default implementation of {@link RelationalEntityMetadata}. - * - * @author Mark Paluch - */ -public class SimpleRelationalEntityMetadata implements RelationalEntityMetadata { - - private final Class type; - private final @Getter RelationalPersistentEntity tableEntity; - - /** - * Creates a new {@link SimpleRelationalEntityMetadata} using the given type and {@link RelationalPersistentEntity} to - * use for table lookups. - * - * @param type must not be {@literal null}. - * @param tableEntity must not be {@literal null}. - */ - public SimpleRelationalEntityMetadata(Class type, RelationalPersistentEntity tableEntity) { - - Assert.notNull(type, "Type must not be null!"); - Assert.notNull(tableEntity, "Table entity must not be null!"); - - this.type = type; - this.tableEntity = tableEntity; - } - - /* (non-Javadoc) - * @see org.springframework.data.repository.core.EntityMetadata#getJavaType() - */ - public Class getJavaType() { - return type; - } - - /* (non-Javadoc) - * @see org.springframework.data.jdbc.repository.query.RelationalEntityMetadata#getTableName() - */ - public String getTableName() { - return tableEntity.getTableName(); - } -} diff --git a/src/main/java/org/springframework/data/relational/repository/query/package-info.java b/src/main/java/org/springframework/data/relational/repository/query/package-info.java deleted file mode 100644 index ccd616a..0000000 --- a/src/main/java/org/springframework/data/relational/repository/query/package-info.java +++ /dev/null @@ -1,7 +0,0 @@ -/** - * Query support for relational database repositories. - */ -@NonNullApi -package org.springframework.data.relational.repository.query; - -import org.springframework.lang.NonNullApi; diff --git a/src/main/java/org/springframework/data/relational/repository/support/MappingRelationalEntityInformation.java b/src/main/java/org/springframework/data/relational/repository/support/MappingRelationalEntityInformation.java deleted file mode 100644 index 6231de0..0000000 --- a/src/main/java/org/springframework/data/relational/repository/support/MappingRelationalEntityInformation.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright 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.data.relational.repository.support; - -import org.springframework.data.relational.core.mapping.RelationalPersistentEntity; -import org.springframework.data.relational.repository.query.RelationalEntityInformation; -import org.springframework.data.repository.core.support.PersistentEntityInformation; -import org.springframework.lang.Nullable; - -/** - * {@link RelationalEntityInformation} implementation using a {@link RelationalPersistentEntity} instance to lookup the - * necessary information. Can be configured with a custom table name. - *

- * Entity types that do not declare an explicit Id type fall back to {@link Long} as Id type. - * - * @author Mark Paluch - */ -public class MappingRelationalEntityInformation extends PersistentEntityInformation - implements RelationalEntityInformation { - - private final RelationalPersistentEntity entityMetadata; - private final @Nullable String customTableName; - private final Class fallbackIdType; - - /** - * Creates a new {@link MappingRelationalEntityInformation} for the given {@link RelationalPersistentEntity}. - * - * @param entity must not be {@literal null}. - */ - public MappingRelationalEntityInformation(RelationalPersistentEntity entity) { - this(entity, null, null); - } - - /** - * Creates a new {@link MappingRelationalEntityInformation} for the given {@link RelationalPersistentEntity} and - * fallback identifier type. - * - * @param entity must not be {@literal null}. - * @param fallbackIdType can be {@literal null}. - */ - public MappingRelationalEntityInformation(RelationalPersistentEntity entity, @Nullable Class fallbackIdType) { - this(entity, null, fallbackIdType); - } - - /** - * Creates a new {@link MappingRelationalEntityInformation} for the given {@link RelationalPersistentEntity} and - * custom table name. - * - * @param entity must not be {@literal null}. - * @param customTableName can be {@literal null}. - */ - public MappingRelationalEntityInformation(RelationalPersistentEntity entity, String customTableName) { - this(entity, customTableName, null); - } - - /** - * Creates a new {@link MappingRelationalEntityInformation} for the given {@link RelationalPersistentEntity}, - * collection name and identifier type. - * - * @param entity must not be {@literal null}. - * @param customTableName can be {@literal null}. - * @param idType can be {@literal null}. - */ - @SuppressWarnings("unchecked") - private MappingRelationalEntityInformation(RelationalPersistentEntity entity, @Nullable String customTableName, - @Nullable Class idType) { - - super(entity); - - this.entityMetadata = entity; - this.customTableName = customTableName; - this.fallbackIdType = idType != null ? idType : (Class) Long.class; - } - - /* (non-Javadoc) - * @see org.springframework.data.relational.repository.query.RelationalEntityInformation#getTableName() - */ - public String getTableName() { - return customTableName == null ? entityMetadata.getTableName() : customTableName; - } - - public String getIdAttribute() { - return entityMetadata.getRequiredIdProperty().getName(); - } - - /* (non-Javadoc) - * @see org.springframework.data.repository.core.support.PersistentEntityInformation#getIdType() - */ - @Override - public Class getIdType() { - - if (this.entityMetadata.hasIdProperty()) { - return super.getIdType(); - } - - return fallbackIdType; - } -} diff --git a/src/main/java/org/springframework/data/relational/repository/support/package-info.java b/src/main/java/org/springframework/data/relational/repository/support/package-info.java deleted file mode 100644 index 28aeb25..0000000 --- a/src/main/java/org/springframework/data/relational/repository/support/package-info.java +++ /dev/null @@ -1,7 +0,0 @@ -/** - * Support infrastructure for query derivation of relational database repositories. - */ -@NonNullApi -package org.springframework.data.relational.repository.support; - -import org.springframework.lang.NonNullApi; diff --git a/src/test/java/org/springframework/data/jdbc/degraph/DependencyTests.java b/src/test/java/org/springframework/data/r2dbc/DependencyTests.java similarity index 95% rename from src/test/java/org/springframework/data/jdbc/degraph/DependencyTests.java rename to src/test/java/org/springframework/data/r2dbc/DependencyTests.java index fe47442..30da212 100644 --- a/src/test/java/org/springframework/data/jdbc/degraph/DependencyTests.java +++ b/src/test/java/org/springframework/data/r2dbc/DependencyTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2017-2018 the original author or authors. + * Copyright 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. @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.jdbc.degraph; +package org.springframework.data.r2dbc; import static de.schauderhaft.degraph.check.JCheck.*; import static org.junit.Assert.*; diff --git a/src/test/java/org/springframework/data/r2dbc/function/DatabaseClientIntegrationTests.java b/src/test/java/org/springframework/data/r2dbc/function/DatabaseClientIntegrationTests.java index 8ab0fda..614d797 100644 --- a/src/test/java/org/springframework/data/r2dbc/function/DatabaseClientIntegrationTests.java +++ b/src/test/java/org/springframework/data/r2dbc/function/DatabaseClientIntegrationTests.java @@ -28,7 +28,7 @@ import org.junit.Test; import org.springframework.dao.DuplicateKeyException; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Sort; -import org.springframework.data.jdbc.testing.R2dbcIntegrationTestSupport; +import org.springframework.data.r2dbc.testing.R2dbcIntegrationTestSupport; import org.springframework.data.relational.core.mapping.Table; import org.springframework.jdbc.core.JdbcTemplate; diff --git a/src/test/java/org/springframework/data/r2dbc/function/TransactionalDatabaseClientIntegrationTests.java b/src/test/java/org/springframework/data/r2dbc/function/TransactionalDatabaseClientIntegrationTests.java index 6a3d19c..31c641e 100644 --- a/src/test/java/org/springframework/data/r2dbc/function/TransactionalDatabaseClientIntegrationTests.java +++ b/src/test/java/org/springframework/data/r2dbc/function/TransactionalDatabaseClientIntegrationTests.java @@ -30,7 +30,7 @@ import java.util.concurrent.ArrayBlockingQueue; import org.junit.Before; import org.junit.Test; -import org.springframework.data.jdbc.testing.R2dbcIntegrationTestSupport; +import org.springframework.data.r2dbc.testing.R2dbcIntegrationTestSupport; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.transaction.NoTransactionException; diff --git a/src/test/java/org/springframework/data/r2dbc/repository/R2dbcRepositoryIntegrationTests.java b/src/test/java/org/springframework/data/r2dbc/repository/R2dbcRepositoryIntegrationTests.java index 4dde9d5..fc2fcb1 100644 --- a/src/test/java/org/springframework/data/r2dbc/repository/R2dbcRepositoryIntegrationTests.java +++ b/src/test/java/org/springframework/data/r2dbc/repository/R2dbcRepositoryIntegrationTests.java @@ -33,12 +33,12 @@ import java.util.Map; import org.junit.Before; import org.junit.Test; import org.springframework.data.annotation.Id; -import org.springframework.data.jdbc.repository.query.Query; -import org.springframework.data.jdbc.testing.R2dbcIntegrationTestSupport; import org.springframework.data.r2dbc.function.DatabaseClient; import org.springframework.data.r2dbc.function.DefaultReactiveDataAccessStrategy; import org.springframework.data.r2dbc.function.TransactionalDatabaseClient; +import org.springframework.data.r2dbc.repository.query.Query; import org.springframework.data.r2dbc.repository.support.R2dbcRepositoryFactory; +import org.springframework.data.r2dbc.testing.R2dbcIntegrationTestSupport; import org.springframework.data.relational.core.conversion.BasicRelationalConverter; import org.springframework.data.relational.core.mapping.RelationalMappingContext; import org.springframework.data.relational.core.mapping.Table; diff --git a/src/test/java/org/springframework/data/r2dbc/repository/query/StringBasedR2dbcQueryUnitTests.java b/src/test/java/org/springframework/data/r2dbc/repository/query/StringBasedR2dbcQueryUnitTests.java index c697b43..bf71533 100644 --- a/src/test/java/org/springframework/data/r2dbc/repository/query/StringBasedR2dbcQueryUnitTests.java +++ b/src/test/java/org/springframework/data/r2dbc/repository/query/StringBasedR2dbcQueryUnitTests.java @@ -27,7 +27,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; -import org.springframework.data.jdbc.repository.query.Query; import org.springframework.data.projection.ProjectionFactory; import org.springframework.data.projection.SpelAwareProxyProjectionFactory; import org.springframework.data.r2dbc.function.DatabaseClient; diff --git a/src/test/java/org/springframework/data/r2dbc/repository/support/SimpleR2dbcRepositoryIntegrationTests.java b/src/test/java/org/springframework/data/r2dbc/repository/support/SimpleR2dbcRepositoryIntegrationTests.java index b5e2dfd..f5a22bc 100644 --- a/src/test/java/org/springframework/data/r2dbc/repository/support/SimpleR2dbcRepositoryIntegrationTests.java +++ b/src/test/java/org/springframework/data/r2dbc/repository/support/SimpleR2dbcRepositoryIntegrationTests.java @@ -33,7 +33,7 @@ import java.util.Map; import org.junit.Before; import org.junit.Test; import org.springframework.data.annotation.Id; -import org.springframework.data.jdbc.testing.R2dbcIntegrationTestSupport; +import org.springframework.data.r2dbc.testing.R2dbcIntegrationTestSupport; import org.springframework.data.r2dbc.function.DatabaseClient; import org.springframework.data.r2dbc.function.DefaultReactiveDataAccessStrategy; import org.springframework.data.r2dbc.function.convert.MappingR2dbcConverter; diff --git a/src/test/java/org/springframework/data/jdbc/testing/ExternalDatabase.java b/src/test/java/org/springframework/data/r2dbc/testing/ExternalDatabase.java similarity index 98% rename from src/test/java/org/springframework/data/jdbc/testing/ExternalDatabase.java rename to src/test/java/org/springframework/data/r2dbc/testing/ExternalDatabase.java index 2c6ebe3..7a021e2 100644 --- a/src/test/java/org/springframework/data/jdbc/testing/ExternalDatabase.java +++ b/src/test/java/org/springframework/data/r2dbc/testing/ExternalDatabase.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.jdbc.testing; +package org.springframework.data.r2dbc.testing; import lombok.Builder; diff --git a/src/test/java/org/springframework/data/jdbc/testing/R2dbcIntegrationTestSupport.java b/src/test/java/org/springframework/data/r2dbc/testing/R2dbcIntegrationTestSupport.java similarity index 94% rename from src/test/java/org/springframework/data/jdbc/testing/R2dbcIntegrationTestSupport.java rename to src/test/java/org/springframework/data/r2dbc/testing/R2dbcIntegrationTestSupport.java index ea99ac4..54ecbf7 100644 --- a/src/test/java/org/springframework/data/jdbc/testing/R2dbcIntegrationTestSupport.java +++ b/src/test/java/org/springframework/data/r2dbc/testing/R2dbcIntegrationTestSupport.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.springframework.data.jdbc.testing; +package org.springframework.data.r2dbc.testing; import io.r2dbc.postgresql.PostgresqlConnectionConfiguration; import io.r2dbc.postgresql.PostgresqlConnectionFactory; @@ -23,7 +23,7 @@ import javax.sql.DataSource; import org.junit.ClassRule; import org.postgresql.ds.PGSimpleDataSource; -import org.springframework.data.jdbc.testing.ExternalDatabase.ProvidedDatabase; +import org.springframework.data.r2dbc.testing.ExternalDatabase.ProvidedDatabase; import org.springframework.jdbc.core.JdbcTemplate; /** diff --git a/src/test/resources/logback.xml b/src/test/resources/logback.xml new file mode 100644 index 0000000..c9be4b4 --- /dev/null +++ b/src/test/resources/logback.xml @@ -0,0 +1,17 @@ + + + + + + %d %5p %40.40c:%4L - %m%n + + + + + + + + + + +