DATAJDBC-182 - Support modifying annotated queries.

Added @Modify for marking queries that perform DML or DDL.
Modifying queries with return type boolean or Boolean return wether the number of updated rows is greater 0.
This shouldn't be used for DML statements since it will always return false.

Original pull request: ##48.
This commit is contained in:
Kazuki Shimizu
2018-03-09 00:16:11 +09:00
committed by Jens Schauder
parent ac4da66d99
commit 73fe1ca93b
5 changed files with 114 additions and 15 deletions

View File

@@ -0,0 +1,33 @@
/*
* 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.jdbc.repository.query;
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;
/**
* Indicates a method should be regarded as modifying query.
*
* @author Kazuki Shimizu
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.ANNOTATION_TYPE })
@Documented
public @interface Modifying {
}

View File

@@ -56,15 +56,17 @@ class JdbcQueryLookupStrategy implements QueryLookupStrategy {
JdbcQueryMethod queryMethod = new JdbcQueryMethod(method, repositoryMetadata, projectionFactory);
Class<?> returnedObjectType = queryMethod.getReturnedObjectType();
RowMapper<?> rowMapper = context.getSimpleTypeHolder().isSimpleType(returnedObjectType)
? SingleColumnRowMapper.newInstance(returnedObjectType, conversionService)
: new EntityRowMapper<>( //
context.getRequiredPersistentEntity(returnedObjectType), //
conversionService, //
context, //
accessStrategy //
);
RowMapper<?> rowMapper = null;
if (!queryMethod.isModifyingQuery()) {
rowMapper = context.getSimpleTypeHolder().isSimpleType(returnedObjectType)
? SingleColumnRowMapper.newInstance(returnedObjectType, conversionService)
: new EntityRowMapper<>( //
context.getRequiredPersistentEntity(returnedObjectType), //
conversionService, //
context, //
accessStrategy //
);
}
return new JdbcRepositoryQuery(queryMethod, context, rowMapper);
}

View File

@@ -18,6 +18,8 @@ package org.springframework.data.jdbc.repository.support;
import java.lang.reflect.Method;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.data.jdbc.repository.query.Modifying;
import org.springframework.data.jdbc.repository.query.Query;
import org.springframework.data.projection.ProjectionFactory;
import org.springframework.data.repository.core.RepositoryMetadata;
@@ -30,6 +32,7 @@ import org.springframework.data.repository.query.QueryMethod;
* Binds method arguments to named parameters in the SQL statement.
*
* @author Jens Schauder
* @author Kazuki Shimizu
*/
public class JdbcQueryMethod extends QueryMethod {
@@ -47,4 +50,15 @@ public class JdbcQueryMethod extends QueryMethod {
return queryAnnotation == null ? null : queryAnnotation.value();
}
/**
* Returns whether the query method is a modifying one.
*
* @return if it's a modifying query, return {@code true}.
*/
@Override
public boolean isModifyingQuery() {
return AnnotationUtils.findAnnotation(method, Modifying.class) != null;
}
}

View File

@@ -55,15 +55,20 @@ class JdbcRepositoryQuery implements RepositoryQuery {
parameters.addValue(parameterName, objects[p.getIndex()]);
});
if (queryMethod.isModifyingQuery()) {
int updatedCount = context.getTemplate().update(query, parameters);
Class<?> returnedObjectType = queryMethod.getReturnedObjectType();
return (returnedObjectType == boolean.class || returnedObjectType == Boolean.class) ? updatedCount != 0 : updatedCount;
}
if (queryMethod.isCollectionQuery() || queryMethod.isStreamQuery()) {
return context.getTemplate().query(query, parameters, rowMapper);
} else {
}
try {
return context.getTemplate().queryForObject(query, parameters, rowMapper);
} catch (EmptyResultDataAccessException e) {
return null;
}
try {
return context.getTemplate().queryForObject(query, parameters, rowMapper);
} catch (EmptyResultDataAccessException e) {
return null;
}
}