DATAJDBC-95 - Saving and loading a trivial entity.
Creation of the necessary sql statements is now dynamic and driven in a trivial way by the entity. Known issues with the solution that need to get fixed later: - SQL generating code is in the repository and should go somewhere else. - Mapping logic is very trivial and should go in a separate place. Original pull request: #5.
This commit is contained in:
committed by
Oliver Gierke
parent
7696f5a1de
commit
38a91d97a0
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright 2017 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;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import org.springframework.data.mapping.PersistentEntity;
|
||||
import org.springframework.data.mapping.PersistentProperty;
|
||||
import org.springframework.data.mapping.PropertyHandler;
|
||||
|
||||
/**
|
||||
* @author Jens Schauder
|
||||
*/
|
||||
class EntityRowMapper<T> implements org.springframework.jdbc.core.RowMapper<T> {
|
||||
|
||||
private final PersistentEntity<T, ?> entity;
|
||||
|
||||
EntityRowMapper(PersistentEntity<T, ?> entity) {
|
||||
this.entity = entity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T mapRow(ResultSet rs, int rowNum) throws SQLException {
|
||||
|
||||
try {
|
||||
|
||||
T t = createInstance();
|
||||
|
||||
entity.doWithProperties((PropertyHandler) property -> {
|
||||
setProperty(rs, t, property);
|
||||
});
|
||||
|
||||
return t;
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(String.format("Could not instantiate %s", entity.getType()));
|
||||
}
|
||||
}
|
||||
|
||||
private T createInstance() throws InstantiationException, IllegalAccessException, InvocationTargetException {
|
||||
return (T) entity.getPersistenceConstructor().getConstructor().newInstance();
|
||||
}
|
||||
|
||||
private void setProperty(ResultSet rs, T t, PersistentProperty property) {
|
||||
|
||||
try {
|
||||
property.getSetter().invoke(t, rs.getObject(property.getName()));
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(String.format("Couldn't set property %s.", property.getName()), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,11 +16,17 @@
|
||||
package org.springframework.data.jdbc.repository;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.sql.DataSource;
|
||||
import org.springframework.data.jdbc.mapping.model.JdbcPersistentEntity;
|
||||
import org.springframework.data.mapping.PersistentProperty;
|
||||
import org.springframework.data.mapping.PropertyHandler;
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
import org.springframework.data.repository.core.EntityInformation;
|
||||
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
|
||||
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;
|
||||
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
|
||||
|
||||
@@ -29,23 +35,25 @@ import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
|
||||
*/
|
||||
public class SimpleJdbcRepository<T, ID extends Serializable> implements CrudRepository<T, ID> {
|
||||
|
||||
private final EntityInformation entityInformation;
|
||||
private final JdbcPersistentEntity<T> entity;
|
||||
private final NamedParameterJdbcOperations template;
|
||||
|
||||
public SimpleJdbcRepository(EntityInformation entityInformation, DataSource dataSource) {
|
||||
this.entityInformation = entityInformation;
|
||||
private final String findOneSql;
|
||||
private final String insertSql;
|
||||
|
||||
public SimpleJdbcRepository(JdbcPersistentEntity<T> entity, DataSource dataSource) {
|
||||
|
||||
this.entity = entity;
|
||||
this.template = new NamedParameterJdbcTemplate(dataSource);
|
||||
|
||||
findOneSql = createFindOneSelectSql();
|
||||
insertSql = createInsertSql();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <S extends T> S save(S entity) {
|
||||
Map<String, Object> parameters = new HashMap<>();
|
||||
parameters.put("id", entityInformation.getId(entity));
|
||||
parameters.put("name", "blah blah");
|
||||
|
||||
template.update(
|
||||
"insert into dummyentity (id, name) values (:id, :name)",
|
||||
parameters);
|
||||
template.update(insertSql, getPropertyMap(entity));
|
||||
|
||||
return entity;
|
||||
}
|
||||
@@ -57,7 +65,12 @@ public class SimpleJdbcRepository<T, ID extends Serializable> implements CrudRep
|
||||
|
||||
@Override
|
||||
public T findOne(ID id) {
|
||||
return null;
|
||||
|
||||
return template.queryForObject(
|
||||
findOneSql,
|
||||
new MapSqlParameterSource("id", id),
|
||||
new EntityRowMapper<T>(entity)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -99,4 +112,45 @@ public class SimpleJdbcRepository<T, ID extends Serializable> implements CrudRep
|
||||
public void deleteAll() {
|
||||
|
||||
}
|
||||
|
||||
private String createFindOneSelectSql() {
|
||||
|
||||
String tableName = entity.getType().getSimpleName();
|
||||
String idColumn = entity.getIdProperty().getName();
|
||||
|
||||
return String.format("select * from %s where %s = :id", tableName, idColumn);
|
||||
}
|
||||
|
||||
private String createInsertSql() {
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
private <S extends T> Map<String, Object> getPropertyMap(final S entity) {
|
||||
|
||||
Map<String, Object> parameters = new HashMap<>();
|
||||
|
||||
this.entity.doWithProperties(new PropertyHandler() {
|
||||
@Override
|
||||
public void doWithPersistentProperty(PersistentProperty persistentProperty) {
|
||||
try {
|
||||
parameters.put(persistentProperty.getName(), persistentProperty.getGetter().invoke(entity));
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(String.format("Couldn't get value of property %s", persistentProperty.getName()));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return parameters;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,13 +39,12 @@ public class JdbcRepositoryFactory extends RepositoryFactorySupport {
|
||||
|
||||
@Override
|
||||
public <T, ID extends Serializable> EntityInformation<T, ID> getEntityInformation(Class<T> aClass) {
|
||||
JdbcPersistentEntity<T> persistentEntity = (JdbcPersistentEntity<T>) context.getPersistentEntity(aClass);
|
||||
return new JdbcPersistentEntityInformation<T, ID>(persistentEntity);
|
||||
return new JdbcPersistentEntityInformation<T, ID>((JdbcPersistentEntity<T>) context.getPersistentEntity(aClass));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object getTargetRepository(RepositoryInformation repositoryInformation) {
|
||||
return new SimpleJdbcRepository(getEntityInformation(repositoryInformation.getDomainType()), dataSource);
|
||||
return new SimpleJdbcRepository(context.getPersistentEntity(repositoryInformation.getDomainType()), dataSource);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user