DATAJDBC-98 - Update implemented.

New instances get saved with an insert statement. Existing instances get updated. Also added some test to find certain corner cases that I feared may cause problems:

- ID properties being not editable (no setter and final).
- ID properties being primitive.
- ID properties not being named "id"

and fixed the issues resulting from those.

Original pull request: #5.
This commit is contained in:
Jens Schauder
2017-02-27 12:38:39 +01:00
committed by Oliver Gierke
parent 21490b8397
commit 1f1753e734
7 changed files with 239 additions and 89 deletions

View File

@@ -23,6 +23,7 @@ import java.util.stream.StreamSupport;
import javax.sql.DataSource;
import org.springframework.data.jdbc.mapping.model.JdbcPersistentEntity;
import org.springframework.data.jdbc.mapping.model.JdbcPersistentProperty;
import org.springframework.data.jdbc.repository.support.JdbcPersistentEntityInformation;
import org.springframework.data.mapping.PropertyHandler;
import org.springframework.data.repository.CrudRepository;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
@@ -37,6 +38,7 @@ import org.springframework.jdbc.support.KeyHolder;
public class SimpleJdbcRepository<T, ID extends Serializable> implements CrudRepository<T, ID> {
private final JdbcPersistentEntity<T> entity;
private final JdbcPersistentEntityInformation<T,ID> entityInformation;
private final NamedParameterJdbcOperations template;
private final SqlGenerator sql;
@@ -45,6 +47,7 @@ public class SimpleJdbcRepository<T, ID extends Serializable> implements CrudRep
public SimpleJdbcRepository(JdbcPersistentEntity<T> entity, DataSource dataSource) {
this.entity = entity;
this.entityInformation = new JdbcPersistentEntityInformation<T, ID>(entity);
this.template = new NamedParameterJdbcTemplate(dataSource);
entityRowMapper = new EntityRowMapper<T>(entity);
@@ -54,14 +57,19 @@ public class SimpleJdbcRepository<T, ID extends Serializable> implements CrudRep
@Override
public <S extends T> S save(S instance) {
KeyHolder holder = new GeneratedKeyHolder();
if (entityInformation.isNew(instance)) {
template.update(
sql.getInsert(),
new MapSqlParameterSource(getPropertyMap(instance)),
holder);
KeyHolder holder = new GeneratedKeyHolder();
entity.setId(instance, holder.getKey());
template.update(
sql.getInsert(),
new MapSqlParameterSource(getPropertyMap(instance)),
holder);
entity.setId(instance, holder.getKey());
} else {
template.update(sql.getUpdate(), getPropertyMap(instance));
}
return instance;
}

View File

@@ -17,6 +17,7 @@ package org.springframework.data.jdbc.repository;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import org.springframework.data.jdbc.mapping.model.JdbcPersistentEntity;
import org.springframework.data.mapping.PropertyHandler;
@@ -37,9 +38,13 @@ class SqlGenerator {
private final String deleteByIdSql;
private final String deleteAllSql;
private final String deleteByListSql;
private final String updateSql;
private final List<String> propertyNames = new ArrayList<>();
<T> SqlGenerator(JdbcPersistentEntity<T> entity) {
entity.doWithProperties((PropertyHandler) persistentProperty -> propertyNames.add(persistentProperty.getName()));
findOneSql = createFindOneSelectSql(entity);
findAllSql = createFindAllSql(entity);
findAllInListSql = createFindAllInListSql(entity);
@@ -48,6 +53,7 @@ class SqlGenerator {
countSql = createCountSql(entity);
insertSql = createInsertSql(entity);
updateSql = createUpdateSql(entity);
deleteByIdSql = createDeleteSql(entity);
deleteAllSql = createDeleteAllSql(entity);
@@ -74,6 +80,10 @@ class SqlGenerator {
return insertSql;
}
String getUpdate() {
return updateSql;
}
String getCount() {
return countSql;
}
@@ -106,22 +116,26 @@ class SqlGenerator {
}
private <T> String createCountSql(JdbcPersistentEntity<T> entity) {
return String.format("select count(*) from %s", entity.getTableName(), entity.getIdColumn());
return String.format("select count(*) from %s", entity.getTableName());
}
private String createInsertSql(JdbcPersistentEntity<?> entity) {
List<String> propertyNames = new ArrayList<>();
entity.doWithProperties((PropertyHandler) persistentProperty -> propertyNames.add(persistentProperty.getName()));
String insertTemplate = "insert into %s (%s) values (%s)";
String tableName = entity.getType().getSimpleName();
String tableColumns = propertyNames.stream().collect(Collectors.joining(", "));
String parameterNames = propertyNames.stream().collect(Collectors.joining(", :", ":", ""));
return String.format(insertTemplate, tableName, tableColumns, parameterNames);
return String.format(insertTemplate, entity.getTableName(), tableColumns, parameterNames);
}
private <T> String createUpdateSql(JdbcPersistentEntity<T> entity) {
String updateTemplate = "update %s set %s where %s = :%s";
String setClause = propertyNames.stream().map(n -> String.format("%s = :%s", n, n)).collect(Collectors.joining(", "));
return String.format(updateTemplate, entity.getTableName(), setClause, entity.getIdColumn(), entity.getIdColumn());
}
private String createDeleteSql(JdbcPersistentEntity entity) {
@@ -133,6 +147,7 @@ class SqlGenerator {
}
private String createDeleteByListSql(JdbcPersistentEntity entity) {
return String.format("delete from %s where id in (:ids)", entity.getTableName());
return String.format("delete from %s where %s in (:ids)", entity.getTableName(), entity.getIdColumn());
}
}