Skip to content

DATAJDBC-98 - update implemented. #4

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jdbc</artifactId>
<version>1.0.0.BUILD-SNAPSHOT</version>
<version>1.0.0.DATAJDBC-98-SNAPSHOT</version>

<name>Spring Data JDBC</name>
<description>Spring Data module for JDBC repositories.</description>
Expand Down Expand Up @@ -67,6 +67,11 @@
<artifactId>spring-beans</artifactId>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
Expand All @@ -84,9 +89,12 @@
<version>2.2.8</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>3.6.2</version>
<scope>test</scope>
</dependency>


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,39 @@
import org.springframework.data.util.TypeInformation;

/**
* meta data a repository might need for implementing persistence operations for instances of type {@code T}
* @author Jens Schauder
*/
public class JdbcPersistentEntity<T> extends BasicPersistentEntity<T, JdbcPersistentProperty> {

private String tableName;
private String idColumn;

public JdbcPersistentEntity(TypeInformation<T> information) {
super(information);
}

public String getTableName() {

if (tableName == null)
tableName = getType().getSimpleName();

return tableName;
}

public String getIdColumn() {

if (idColumn == null)
idColumn = getIdProperty().getName();

return idColumn;
}

public Object getIdValue(T instance) {
return getPropertyAccessor(instance).getProperty(getIdProperty());
}

public void setId(T instance, Object value) {
getPropertyAccessor(instance).setProperty(getIdProperty(),value);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
import org.springframework.data.mapping.model.SimpleTypeHolder;

/**
* meta data about a property to be used by repository implementations.
*
* @author Jens Schauder
*/
public class JdbcPersistentProperty extends AnnotationBasedPersistentProperty<JdbcPersistentProperty> {
Expand All @@ -43,4 +45,8 @@ public JdbcPersistentProperty(Field field, PropertyDescriptor propertyDescriptor
protected Association<JdbcPersistentProperty> createAssociation() {
return null;
}

public String getColumnName() {
return getName();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
* 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.sql.ResultSet;
import java.sql.SQLException;
import org.springframework.data.convert.ClassGeneratingEntityInstantiator;
import org.springframework.data.convert.EntityInstantiator;
import org.springframework.data.jdbc.mapping.model.JdbcPersistentEntity;
import org.springframework.data.jdbc.mapping.model.JdbcPersistentProperty;
import org.springframework.data.mapping.PersistentProperty;
import org.springframework.data.mapping.PreferredConstructor;
import org.springframework.data.mapping.PropertyHandler;
import org.springframework.data.mapping.model.MappingException;
import org.springframework.data.mapping.model.ParameterValueProvider;

/**
* maps a ResultSet to an entity of type {@code T}
*
* @author Jens Schauder
*/
class EntityRowMapper<T> implements org.springframework.jdbc.core.RowMapper<T> {

private final JdbcPersistentEntity<T> entity;

private final EntityInstantiator instantiator = new ClassGeneratingEntityInstantiator();

EntityRowMapper(JdbcPersistentEntity<T> entity) {
this.entity = entity;
}

@Override
public T mapRow(ResultSet rs, int rowNum) throws SQLException {

T t = createInstance(rs);

entity.doWithProperties((PropertyHandler) property -> {
setProperty(rs, t, property);
});

return t;
}

private T createInstance(ResultSet rs) {
return instantiator.createInstance(entity, new ParameterValueProvider<JdbcPersistentProperty>() {
@Override
public <T> T getParameterValue(PreferredConstructor.Parameter<T, JdbcPersistentProperty> parameter) {
try {
return (T) rs.getObject(parameter.getName());
} catch (SQLException e) {
throw new MappingException(String.format("Couldn't read column %s from ResultSet.", parameter.getName()));
}
}
});
}

private void setProperty(ResultSet rs, T t, PersistentProperty property) {

try {
entity.getPropertyAccessor(t).setProperty(property, rs.getObject(property.getName()));
} catch (Exception e) {
throw new RuntimeException(String.format("Couldn't set property %s.", property.getName()), e);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,85 +18,149 @@
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;
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.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;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;

/**
* @author Jens Schauder
*/
public class SimpleJdbcRepository<T, ID extends Serializable> implements CrudRepository<T, ID> {

private final EntityInformation entityInformation;
private final JdbcPersistentEntity<T> entity;
private final JdbcPersistentEntityInformation<T,ID> entityInformation;
private final NamedParameterJdbcOperations template;
private final SqlGenerator sql;

public SimpleJdbcRepository(EntityInformation entityInformation, DataSource dataSource) {
this.entityInformation = entityInformation;
private final EntityRowMapper<T> entityRowMapper;

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);
sql = new SqlGenerator(entity);
}

@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");
public <S extends T> S save(S instance) {

template.update(
"insert into dummyentity (id, name) values (:id, :name)",
parameters);
if (entityInformation.isNew(instance)) {

return entity;
KeyHolder holder = new GeneratedKeyHolder();

template.update(
sql.getInsert(),
new MapSqlParameterSource(getPropertyMap(instance)),
holder);

entity.setId(instance, holder.getKey());
} else {
template.update(sql.getUpdate(), getPropertyMap(instance));
}

return instance;
}

@Override
public <S extends T> Iterable<S> save(Iterable<S> entities) {
return null;

entities.forEach(this::save);

return entities;
}

@Override
public T findOne(ID id) {
return null;

return template.queryForObject(
sql.getFindOne(),
new MapSqlParameterSource("id", id),
entityRowMapper
);
}

@Override
public boolean exists(ID id) {
return false;

return template.queryForObject(
sql.getExists(),
new MapSqlParameterSource("id", id),
Boolean.class
);
}

@Override
public Iterable<T> findAll() {
return null;
return template.query(sql.getFindAll(), entityRowMapper);
}

@Override
public Iterable<T> findAll(Iterable<ID> ids) {
return null;
return template.query(sql.getFindAllInList(), new MapSqlParameterSource("ids", ids), entityRowMapper);
}

@Override
public long count() {
return 0;
return template.getJdbcOperations().queryForObject(sql.getCount(), Long.class);
}

@Override
public void delete(ID id) {

template.update(sql.getDeleteById(), new MapSqlParameterSource("id", id));
}

@Override
public void delete(T entity) {
public void delete(T instance) {

template.update(
sql.getDeleteById(),
new MapSqlParameterSource("id",
entity.getIdValue(instance)));
}

@Override
public void delete(Iterable<? extends T> entities) {

template.update(
sql.getDeleteByList(),
new MapSqlParameterSource("ids",
StreamSupport
.stream(entities.spliterator(), false)
.map(entity::getIdValue)
.collect(Collectors.toList())
)
);
}

@Override
public void deleteAll() {
template.getJdbcOperations().update(sql.getDeleteAll());
}

private <S extends T> Map<String, Object> getPropertyMap(final S instance) {

Map<String, Object> parameters = new HashMap<>();

this.entity.doWithProperties(new PropertyHandler<JdbcPersistentProperty>() {
@Override
public void doWithPersistentProperty(JdbcPersistentProperty persistentProperty) {
parameters.put(persistentProperty.getColumnName(), entity.getPropertyAccessor(instance).getProperty(persistentProperty));
}
});

return parameters;
}
}
Loading