|
@@ -20,7 +20,6 @@ import com.baomidou.mybatisplus.core.plugins.IgnoreStrategy;
|
|
import com.baomidou.mybatisplus.core.plugins.InterceptorIgnoreHelper;
|
|
import com.baomidou.mybatisplus.core.plugins.InterceptorIgnoreHelper;
|
|
import com.baomidou.mybatisplus.core.toolkit.GlobalConfigUtils;
|
|
import com.baomidou.mybatisplus.core.toolkit.GlobalConfigUtils;
|
|
import com.baomidou.mybatisplus.core.toolkit.StringPool;
|
|
import com.baomidou.mybatisplus.core.toolkit.StringPool;
|
|
-import lombok.Getter;
|
|
|
|
import org.apache.ibatis.annotations.*;
|
|
import org.apache.ibatis.annotations.*;
|
|
import org.apache.ibatis.annotations.ResultMap;
|
|
import org.apache.ibatis.annotations.ResultMap;
|
|
import org.apache.ibatis.annotations.Options.FlushCachePolicy;
|
|
import org.apache.ibatis.annotations.Options.FlushCachePolicy;
|
|
@@ -29,7 +28,6 @@ import org.apache.ibatis.builder.BuilderException;
|
|
import org.apache.ibatis.builder.CacheRefResolver;
|
|
import org.apache.ibatis.builder.CacheRefResolver;
|
|
import org.apache.ibatis.builder.IncompleteElementException;
|
|
import org.apache.ibatis.builder.IncompleteElementException;
|
|
import org.apache.ibatis.builder.annotation.MapperAnnotationBuilder;
|
|
import org.apache.ibatis.builder.annotation.MapperAnnotationBuilder;
|
|
-import org.apache.ibatis.builder.annotation.MethodResolver;
|
|
|
|
import org.apache.ibatis.builder.annotation.ProviderSqlSource;
|
|
import org.apache.ibatis.builder.annotation.ProviderSqlSource;
|
|
import org.apache.ibatis.cursor.Cursor;
|
|
import org.apache.ibatis.cursor.Cursor;
|
|
import org.apache.ibatis.executor.keygen.Jdbc3KeyGenerator;
|
|
import org.apache.ibatis.executor.keygen.Jdbc3KeyGenerator;
|
|
@@ -121,32 +119,18 @@ public class MybatisMapperAnnotationBuilder extends MapperAnnotationBuilder {
|
|
configuration.addIncompleteMethod(new InjectorResolver(this));
|
|
configuration.addIncompleteMethod(new InjectorResolver(this));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- parsePendingMethods();
|
|
|
|
|
|
+ configuration.parsePendingMethods(false);
|
|
}
|
|
}
|
|
|
|
|
|
void parserInjector() {
|
|
void parserInjector() {
|
|
GlobalConfigUtils.getSqlInjector(configuration).inspectInject(assistant, type);
|
|
GlobalConfigUtils.getSqlInjector(configuration).inspectInject(assistant, type);
|
|
}
|
|
}
|
|
|
|
|
|
- private boolean canHaveStatement(Method method) {
|
|
|
|
|
|
+ private static boolean canHaveStatement(Method method) {
|
|
// issue #237
|
|
// issue #237
|
|
return !method.isBridge() && !method.isDefault();
|
|
return !method.isBridge() && !method.isDefault();
|
|
}
|
|
}
|
|
|
|
|
|
- private void parsePendingMethods() {
|
|
|
|
- Collection<MethodResolver> incompleteMethods = configuration.getIncompleteMethods();
|
|
|
|
- synchronized (incompleteMethods) {
|
|
|
|
- Iterator<MethodResolver> iter = incompleteMethods.iterator();
|
|
|
|
- while (iter.hasNext()) {
|
|
|
|
- try {
|
|
|
|
- iter.next().resolve();
|
|
|
|
- iter.remove();
|
|
|
|
- } catch (IncompleteElementException e) {
|
|
|
|
- // This method is still missing a resource
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
|
|
|
|
private void loadXmlResource() {
|
|
private void loadXmlResource() {
|
|
// Spring may not know the real resource name so we check a flag
|
|
// Spring may not know the real resource name so we check a flag
|
|
@@ -177,7 +161,8 @@ public class MybatisMapperAnnotationBuilder extends MapperAnnotationBuilder {
|
|
Integer size = cacheDomain.size() == 0 ? null : cacheDomain.size();
|
|
Integer size = cacheDomain.size() == 0 ? null : cacheDomain.size();
|
|
Long flushInterval = cacheDomain.flushInterval() == 0 ? null : cacheDomain.flushInterval();
|
|
Long flushInterval = cacheDomain.flushInterval() == 0 ? null : cacheDomain.flushInterval();
|
|
Properties props = convertToProperties(cacheDomain.properties());
|
|
Properties props = convertToProperties(cacheDomain.properties());
|
|
- assistant.useNewCache(cacheDomain.implementation(), cacheDomain.eviction(), flushInterval, size, cacheDomain.readWrite(), cacheDomain.blocking(), props);
|
|
|
|
|
|
+ assistant.useNewCache(cacheDomain.implementation(), cacheDomain.eviction(), flushInterval, size,
|
|
|
|
+ cacheDomain.readWrite(), cacheDomain.blocking(), props);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -187,8 +172,7 @@ public class MybatisMapperAnnotationBuilder extends MapperAnnotationBuilder {
|
|
}
|
|
}
|
|
Properties props = new Properties();
|
|
Properties props = new Properties();
|
|
for (Property property : properties) {
|
|
for (Property property : properties) {
|
|
- props.setProperty(property.name(),
|
|
|
|
- PropertyParser.parse(property.value(), configuration.getVariables()));
|
|
|
|
|
|
+ props.setProperty(property.name(), PropertyParser.parse(property.value(), configuration.getVariables()));
|
|
}
|
|
}
|
|
return props;
|
|
return props;
|
|
}
|
|
}
|
|
@@ -204,7 +188,7 @@ public class MybatisMapperAnnotationBuilder extends MapperAnnotationBuilder {
|
|
if (refType != void.class && !refName.isEmpty()) {
|
|
if (refType != void.class && !refName.isEmpty()) {
|
|
throw new BuilderException("Cannot use both value() and name() attribute in the @CacheNamespaceRef");
|
|
throw new BuilderException("Cannot use both value() and name() attribute in the @CacheNamespaceRef");
|
|
}
|
|
}
|
|
- String namespace = (refType != void.class) ? refType.getName() : refName;
|
|
|
|
|
|
+ String namespace = refType != void.class ? refType.getName() : refName;
|
|
try {
|
|
try {
|
|
assistant.useCacheRef(namespace);
|
|
assistant.useCacheRef(namespace);
|
|
} catch (IncompleteElementException e) {
|
|
} catch (IncompleteElementException e) {
|
|
@@ -214,7 +198,7 @@ public class MybatisMapperAnnotationBuilder extends MapperAnnotationBuilder {
|
|
}
|
|
}
|
|
|
|
|
|
private String parseResultMap(Method method) {
|
|
private String parseResultMap(Method method) {
|
|
- Class<?> returnType = getReturnType(method);
|
|
|
|
|
|
+ Class<?> returnType = getReturnType(method, type);
|
|
Arg[] args = method.getAnnotationsByType(Arg.class);
|
|
Arg[] args = method.getAnnotationsByType(Arg.class);
|
|
Result[] results = method.getAnnotationsByType(Result.class);
|
|
Result[] results = method.getAnnotationsByType(Result.class);
|
|
TypeDiscriminator typeDiscriminator = method.getAnnotation(TypeDiscriminator.class);
|
|
TypeDiscriminator typeDiscriminator = method.getAnnotation(TypeDiscriminator.class);
|
|
@@ -226,24 +210,26 @@ public class MybatisMapperAnnotationBuilder extends MapperAnnotationBuilder {
|
|
private String generateResultMapName(Method method) {
|
|
private String generateResultMapName(Method method) {
|
|
Results results = method.getAnnotation(Results.class);
|
|
Results results = method.getAnnotation(Results.class);
|
|
if (results != null && !results.id().isEmpty()) {
|
|
if (results != null && !results.id().isEmpty()) {
|
|
- return type.getName() + StringPool.DOT + results.id();
|
|
|
|
|
|
+ return type.getName() + "." + results.id();
|
|
}
|
|
}
|
|
StringBuilder suffix = new StringBuilder();
|
|
StringBuilder suffix = new StringBuilder();
|
|
for (Class<?> c : method.getParameterTypes()) {
|
|
for (Class<?> c : method.getParameterTypes()) {
|
|
- suffix.append(StringPool.DASH);
|
|
|
|
|
|
+ suffix.append("-");
|
|
suffix.append(c.getSimpleName());
|
|
suffix.append(c.getSimpleName());
|
|
}
|
|
}
|
|
if (suffix.length() < 1) {
|
|
if (suffix.length() < 1) {
|
|
suffix.append("-void");
|
|
suffix.append("-void");
|
|
}
|
|
}
|
|
- return type.getName() + StringPool.DOT + method.getName() + suffix;
|
|
|
|
|
|
+ return type.getName() + "." + method.getName() + suffix;
|
|
}
|
|
}
|
|
|
|
|
|
- private void applyResultMap(String resultMapId, Class<?> returnType, Arg[] args, Result[] results, TypeDiscriminator discriminator) {
|
|
|
|
|
|
+ private void applyResultMap(String resultMapId, Class<?> returnType, Arg[] args, Result[] results,
|
|
|
|
+ TypeDiscriminator discriminator) {
|
|
List<ResultMapping> resultMappings = new ArrayList<>();
|
|
List<ResultMapping> resultMappings = new ArrayList<>();
|
|
applyConstructorArgs(args, returnType, resultMappings);
|
|
applyConstructorArgs(args, returnType, resultMappings);
|
|
applyResults(results, returnType, resultMappings);
|
|
applyResults(results, returnType, resultMappings);
|
|
Discriminator disc = applyDiscriminator(resultMapId, returnType, discriminator);
|
|
Discriminator disc = applyDiscriminator(resultMapId, returnType, discriminator);
|
|
|
|
+ // TODO add AutoMappingBehaviour
|
|
assistant.addResultMap(resultMapId, returnType, null, disc, resultMappings, null);
|
|
assistant.addResultMap(resultMapId, returnType, null, disc, resultMappings, null);
|
|
createDiscriminatorResultMaps(resultMapId, returnType, discriminator);
|
|
createDiscriminatorResultMaps(resultMapId, returnType, discriminator);
|
|
}
|
|
}
|
|
@@ -251,11 +237,12 @@ public class MybatisMapperAnnotationBuilder extends MapperAnnotationBuilder {
|
|
private void createDiscriminatorResultMaps(String resultMapId, Class<?> resultType, TypeDiscriminator discriminator) {
|
|
private void createDiscriminatorResultMaps(String resultMapId, Class<?> resultType, TypeDiscriminator discriminator) {
|
|
if (discriminator != null) {
|
|
if (discriminator != null) {
|
|
for (Case c : discriminator.cases()) {
|
|
for (Case c : discriminator.cases()) {
|
|
- String caseResultMapId = resultMapId + StringPool.DASH + c.value();
|
|
|
|
|
|
+ String caseResultMapId = resultMapId + "-" + c.value();
|
|
List<ResultMapping> resultMappings = new ArrayList<>();
|
|
List<ResultMapping> resultMappings = new ArrayList<>();
|
|
// issue #136
|
|
// issue #136
|
|
applyConstructorArgs(c.constructArgs(), resultType, resultMappings);
|
|
applyConstructorArgs(c.constructArgs(), resultType, resultMappings);
|
|
applyResults(c.results(), resultType, resultMappings);
|
|
applyResults(c.results(), resultType, resultMappings);
|
|
|
|
+ // TODO add AutoMappingBehaviour
|
|
assistant.addResultMap(caseResultMapId, c.type(), resultMapId, null, resultMappings, null);
|
|
assistant.addResultMap(caseResultMapId, c.type(), resultMapId, null, resultMappings, null);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -267,13 +254,13 @@ public class MybatisMapperAnnotationBuilder extends MapperAnnotationBuilder {
|
|
Class<?> javaType = discriminator.javaType() == void.class ? String.class : discriminator.javaType();
|
|
Class<?> javaType = discriminator.javaType() == void.class ? String.class : discriminator.javaType();
|
|
JdbcType jdbcType = discriminator.jdbcType() == JdbcType.UNDEFINED ? null : discriminator.jdbcType();
|
|
JdbcType jdbcType = discriminator.jdbcType() == JdbcType.UNDEFINED ? null : discriminator.jdbcType();
|
|
@SuppressWarnings("unchecked")
|
|
@SuppressWarnings("unchecked")
|
|
- Class<? extends TypeHandler<?>> typeHandler = (Class<? extends TypeHandler<?>>)
|
|
|
|
- (discriminator.typeHandler() == UnknownTypeHandler.class ? null : discriminator.typeHandler());
|
|
|
|
|
|
+ Class<? extends TypeHandler<?>> typeHandler = (Class<? extends TypeHandler<?>>) (discriminator
|
|
|
|
+ .typeHandler() == UnknownTypeHandler.class ? null : discriminator.typeHandler());
|
|
Case[] cases = discriminator.cases();
|
|
Case[] cases = discriminator.cases();
|
|
Map<String, String> discriminatorMap = new HashMap<>();
|
|
Map<String, String> discriminatorMap = new HashMap<>();
|
|
for (Case c : cases) {
|
|
for (Case c : cases) {
|
|
String value = c.value();
|
|
String value = c.value();
|
|
- String caseResultMapId = resultMapId + StringPool.DASH + value;
|
|
|
|
|
|
+ String caseResultMapId = resultMapId + "-" + value;
|
|
discriminatorMap.put(value, caseResultMapId);
|
|
discriminatorMap.put(value, caseResultMapId);
|
|
}
|
|
}
|
|
return assistant.buildDiscriminator(resultType, column, javaType, jdbcType, typeHandler, discriminatorMap);
|
|
return assistant.buildDiscriminator(resultType, column, javaType, jdbcType, typeHandler, discriminatorMap);
|
|
@@ -286,19 +273,23 @@ public class MybatisMapperAnnotationBuilder extends MapperAnnotationBuilder {
|
|
final LanguageDriver languageDriver = getLanguageDriver(method);
|
|
final LanguageDriver languageDriver = getLanguageDriver(method);
|
|
|
|
|
|
getAnnotationWrapper(method, true, statementAnnotationTypes).ifPresent(statementAnnotation -> {
|
|
getAnnotationWrapper(method, true, statementAnnotationTypes).ifPresent(statementAnnotation -> {
|
|
- final SqlSource sqlSource = buildSqlSource(statementAnnotation.getAnnotation(), parameterTypeClass, languageDriver, method);
|
|
|
|
|
|
+ final SqlSource sqlSource = buildSqlSource(statementAnnotation.getAnnotation(), parameterTypeClass,
|
|
|
|
+ languageDriver, method);
|
|
final SqlCommandType sqlCommandType = statementAnnotation.getSqlCommandType();
|
|
final SqlCommandType sqlCommandType = statementAnnotation.getSqlCommandType();
|
|
- final Options options = getAnnotationWrapper(method, false, Options.class).map(x -> (Options) x.getAnnotation()).orElse(null);
|
|
|
|
- final String mappedStatementId = type.getName() + StringPool.DOT + method.getName();
|
|
|
|
|
|
+ final Options options = getAnnotationWrapper(method, false, Options.class).map(x -> (Options) x.getAnnotation())
|
|
|
|
+ .orElse(null);
|
|
|
|
+ final String mappedStatementId = type.getName() + "." + method.getName();
|
|
|
|
|
|
final KeyGenerator keyGenerator;
|
|
final KeyGenerator keyGenerator;
|
|
String keyProperty = null;
|
|
String keyProperty = null;
|
|
String keyColumn = null;
|
|
String keyColumn = null;
|
|
if (SqlCommandType.INSERT.equals(sqlCommandType) || SqlCommandType.UPDATE.equals(sqlCommandType)) {
|
|
if (SqlCommandType.INSERT.equals(sqlCommandType) || SqlCommandType.UPDATE.equals(sqlCommandType)) {
|
|
// first check for SelectKey annotation - that overrides everything else
|
|
// first check for SelectKey annotation - that overrides everything else
|
|
- SelectKey selectKey = getAnnotationWrapper(method, false, SelectKey.class).map(x -> (SelectKey) x.getAnnotation()).orElse(null);
|
|
|
|
|
|
+ SelectKey selectKey = getAnnotationWrapper(method, false, SelectKey.class)
|
|
|
|
+ .map(x -> (SelectKey) x.getAnnotation()).orElse(null);
|
|
if (selectKey != null) {
|
|
if (selectKey != null) {
|
|
- keyGenerator = handleSelectKeyAnnotation(selectKey, mappedStatementId, getParameterType(method), languageDriver);
|
|
|
|
|
|
+ keyGenerator = handleSelectKeyAnnotation(selectKey, mappedStatementId, getParameterType(method),
|
|
|
|
+ languageDriver);
|
|
keyProperty = selectKey.keyProperty();
|
|
keyProperty = selectKey.keyProperty();
|
|
} else if (options == null) {
|
|
} else if (options == null) {
|
|
keyGenerator = configuration.isUseGeneratedKeys() ? Jdbc3KeyGenerator.INSTANCE : NoKeyGenerator.INSTANCE;
|
|
keyGenerator = configuration.isUseGeneratedKeys() ? Jdbc3KeyGenerator.INSTANCE : NoKeyGenerator.INSTANCE;
|
|
@@ -325,7 +316,8 @@ public class MybatisMapperAnnotationBuilder extends MapperAnnotationBuilder {
|
|
flushCache = false;
|
|
flushCache = false;
|
|
}
|
|
}
|
|
useCache = options.useCache();
|
|
useCache = options.useCache();
|
|
- fetchSize = options.fetchSize() > -1 || options.fetchSize() == Integer.MIN_VALUE ? options.fetchSize() : null; //issue #348
|
|
|
|
|
|
+ // issue #348
|
|
|
|
+ fetchSize = options.fetchSize() > -1 || options.fetchSize() == Integer.MIN_VALUE ? options.fetchSize() : null;
|
|
timeout = options.timeout() > -1 ? options.timeout() : null;
|
|
timeout = options.timeout() > -1 ? options.timeout() : null;
|
|
statementType = options.statementType();
|
|
statementType = options.statementType();
|
|
if (options.resultSetType() != ResultSetType.DEFAULT) {
|
|
if (options.resultSetType() != ResultSetType.DEFAULT) {
|
|
@@ -337,35 +329,19 @@ public class MybatisMapperAnnotationBuilder extends MapperAnnotationBuilder {
|
|
if (isSelect) {
|
|
if (isSelect) {
|
|
ResultMap resultMapAnnotation = method.getAnnotation(ResultMap.class);
|
|
ResultMap resultMapAnnotation = method.getAnnotation(ResultMap.class);
|
|
if (resultMapAnnotation != null) {
|
|
if (resultMapAnnotation != null) {
|
|
- resultMapId = String.join(StringPool.COMMA, resultMapAnnotation.value());
|
|
|
|
|
|
+ resultMapId = String.join(",", resultMapAnnotation.value());
|
|
} else {
|
|
} else {
|
|
resultMapId = generateResultMapName(method);
|
|
resultMapId = generateResultMapName(method);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- assistant.addMappedStatement(
|
|
|
|
- mappedStatementId,
|
|
|
|
- sqlSource,
|
|
|
|
- statementType,
|
|
|
|
- sqlCommandType,
|
|
|
|
- fetchSize,
|
|
|
|
- timeout,
|
|
|
|
|
|
+ assistant.addMappedStatement(mappedStatementId, sqlSource, statementType, sqlCommandType, fetchSize, timeout,
|
|
// ParameterMapID
|
|
// ParameterMapID
|
|
- null,
|
|
|
|
- parameterTypeClass,
|
|
|
|
- resultMapId,
|
|
|
|
- getReturnType(method),
|
|
|
|
- resultSetType,
|
|
|
|
- flushCache,
|
|
|
|
- useCache,
|
|
|
|
- false,
|
|
|
|
- keyGenerator,
|
|
|
|
- keyProperty,
|
|
|
|
- keyColumn,
|
|
|
|
- statementAnnotation.getDatabaseId(),
|
|
|
|
- languageDriver,
|
|
|
|
|
|
+ null, parameterTypeClass, resultMapId, getReturnType(method, type), resultSetType, flushCache, useCache,
|
|
|
|
+ // TODO gcode issue #577
|
|
|
|
+ false, keyGenerator, keyProperty, keyColumn, statementAnnotation.getDatabaseId(), languageDriver,
|
|
// ResultSets
|
|
// ResultSets
|
|
- options != null ? nullOrEmpty(options.resultSets()) : null);
|
|
|
|
|
|
+ options != null ? nullOrEmpty(options.resultSets()) : null, statementAnnotation.isDirtySelect());
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
@@ -382,7 +358,8 @@ public class MybatisMapperAnnotationBuilder extends MapperAnnotationBuilder {
|
|
Class<?> parameterType = null;
|
|
Class<?> parameterType = null;
|
|
Class<?>[] parameterTypes = method.getParameterTypes();
|
|
Class<?>[] parameterTypes = method.getParameterTypes();
|
|
for (Class<?> currentParameterType : parameterTypes) {
|
|
for (Class<?> currentParameterType : parameterTypes) {
|
|
- if (!RowBounds.class.isAssignableFrom(currentParameterType) && !ResultHandler.class.isAssignableFrom(currentParameterType)) {
|
|
|
|
|
|
+ if (!RowBounds.class.isAssignableFrom(currentParameterType)
|
|
|
|
+ && !ResultHandler.class.isAssignableFrom(currentParameterType)) {
|
|
if (parameterType == null) {
|
|
if (parameterType == null) {
|
|
parameterType = currentParameterType;
|
|
parameterType = currentParameterType;
|
|
} else {
|
|
} else {
|
|
@@ -394,7 +371,7 @@ public class MybatisMapperAnnotationBuilder extends MapperAnnotationBuilder {
|
|
return parameterType;
|
|
return parameterType;
|
|
}
|
|
}
|
|
|
|
|
|
- private Class<?> getReturnType(Method method) {
|
|
|
|
|
|
+ private static Class<?> getReturnType(Method method, Class<?> type) {
|
|
Class<?> returnType = method.getReturnType();
|
|
Class<?> returnType = method.getReturnType();
|
|
Type resolvedReturnType = TypeParameterResolver.resolveReturnType(method, type);
|
|
Type resolvedReturnType = TypeParameterResolver.resolveReturnType(method, type);
|
|
if (resolvedReturnType instanceof Class) {
|
|
if (resolvedReturnType instanceof Class) {
|
|
@@ -467,24 +444,15 @@ public class MybatisMapperAnnotationBuilder extends MapperAnnotationBuilder {
|
|
flags.add(ResultFlag.ID);
|
|
flags.add(ResultFlag.ID);
|
|
}
|
|
}
|
|
@SuppressWarnings("unchecked")
|
|
@SuppressWarnings("unchecked")
|
|
- Class<? extends TypeHandler<?>> typeHandler = (Class<? extends TypeHandler<?>>)
|
|
|
|
- ((result.typeHandler() == UnknownTypeHandler.class) ? null : result.typeHandler());
|
|
|
|
|
|
+ Class<? extends TypeHandler<?>> typeHandler = (Class<? extends TypeHandler<?>>) (result
|
|
|
|
+ .typeHandler() == UnknownTypeHandler.class ? null : result.typeHandler());
|
|
boolean hasNestedResultMap = hasNestedResultMap(result);
|
|
boolean hasNestedResultMap = hasNestedResultMap(result);
|
|
- ResultMapping resultMapping = assistant.buildResultMapping(
|
|
|
|
- resultType,
|
|
|
|
- nullOrEmpty(result.property()),
|
|
|
|
- nullOrEmpty(result.column()),
|
|
|
|
- result.javaType() == void.class ? null : result.javaType(),
|
|
|
|
|
|
+ ResultMapping resultMapping = assistant.buildResultMapping(resultType, nullOrEmpty(result.property()),
|
|
|
|
+ nullOrEmpty(result.column()), result.javaType() == void.class ? null : result.javaType(),
|
|
result.jdbcType() == JdbcType.UNDEFINED ? null : result.jdbcType(),
|
|
result.jdbcType() == JdbcType.UNDEFINED ? null : result.jdbcType(),
|
|
hasNestedSelect(result) ? nestedSelectId(result) : null,
|
|
hasNestedSelect(result) ? nestedSelectId(result) : null,
|
|
- hasNestedResultMap ? nestedResultMapId(result) : null,
|
|
|
|
- null,
|
|
|
|
- hasNestedResultMap ? findColumnPrefix(result) : null,
|
|
|
|
- typeHandler,
|
|
|
|
- flags,
|
|
|
|
- null,
|
|
|
|
- null,
|
|
|
|
- isLazy(result));
|
|
|
|
|
|
+ hasNestedResultMap ? nestedResultMapId(result) : null, null,
|
|
|
|
+ hasNestedResultMap ? findColumnPrefix(result) : null, typeHandler, flags, null, null, isLazy(result));
|
|
resultMappings.add(resultMapping);
|
|
resultMappings.add(resultMapping);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -551,23 +519,12 @@ public class MybatisMapperAnnotationBuilder extends MapperAnnotationBuilder {
|
|
flags.add(ResultFlag.ID);
|
|
flags.add(ResultFlag.ID);
|
|
}
|
|
}
|
|
@SuppressWarnings("unchecked")
|
|
@SuppressWarnings("unchecked")
|
|
- Class<? extends TypeHandler<?>> typeHandler = (Class<? extends TypeHandler<?>>)
|
|
|
|
- (arg.typeHandler() == UnknownTypeHandler.class ? null : arg.typeHandler());
|
|
|
|
- ResultMapping resultMapping = assistant.buildResultMapping(
|
|
|
|
- resultType,
|
|
|
|
- nullOrEmpty(arg.name()),
|
|
|
|
- nullOrEmpty(arg.column()),
|
|
|
|
- arg.javaType() == void.class ? null : arg.javaType(),
|
|
|
|
- arg.jdbcType() == JdbcType.UNDEFINED ? null : arg.jdbcType(),
|
|
|
|
- nullOrEmpty(arg.select()),
|
|
|
|
- nullOrEmpty(arg.resultMap()),
|
|
|
|
- null,
|
|
|
|
- nullOrEmpty(arg.columnPrefix()),
|
|
|
|
- typeHandler,
|
|
|
|
- flags,
|
|
|
|
- null,
|
|
|
|
- null,
|
|
|
|
- false);
|
|
|
|
|
|
+ Class<? extends TypeHandler<?>> typeHandler = (Class<? extends TypeHandler<?>>) (arg
|
|
|
|
+ .typeHandler() == UnknownTypeHandler.class ? null : arg.typeHandler());
|
|
|
|
+ ResultMapping resultMapping = assistant.buildResultMapping(resultType, nullOrEmpty(arg.name()),
|
|
|
|
+ nullOrEmpty(arg.column()), arg.javaType() == void.class ? null : arg.javaType(),
|
|
|
|
+ arg.jdbcType() == JdbcType.UNDEFINED ? null : arg.jdbcType(), nullOrEmpty(arg.select()),
|
|
|
|
+ nullOrEmpty(arg.resultMap()), null, nullOrEmpty(arg.columnPrefix()), typeHandler, flags, null, null, false);
|
|
resultMappings.add(resultMapping);
|
|
resultMappings.add(resultMapping);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -576,7 +533,8 @@ public class MybatisMapperAnnotationBuilder extends MapperAnnotationBuilder {
|
|
return value == null || value.trim().length() == 0 ? null : value;
|
|
return value == null || value.trim().length() == 0 ? null : value;
|
|
}
|
|
}
|
|
|
|
|
|
- private KeyGenerator handleSelectKeyAnnotation(SelectKey selectKeyAnnotation, String baseStatementId, Class<?> parameterTypeClass, LanguageDriver languageDriver) {
|
|
|
|
|
|
+ private KeyGenerator handleSelectKeyAnnotation(SelectKey selectKeyAnnotation, String baseStatementId,
|
|
|
|
+ Class<?> parameterTypeClass, LanguageDriver languageDriver) {
|
|
String id = baseStatementId + SelectKeyGenerator.SELECT_KEY_SUFFIX;
|
|
String id = baseStatementId + SelectKeyGenerator.SELECT_KEY_SUFFIX;
|
|
Class<?> resultTypeClass = selectKeyAnnotation.resultType();
|
|
Class<?> resultTypeClass = selectKeyAnnotation.resultType();
|
|
StatementType statementType = selectKeyAnnotation.statementType();
|
|
StatementType statementType = selectKeyAnnotation.statementType();
|
|
@@ -598,9 +556,9 @@ public class MybatisMapperAnnotationBuilder extends MapperAnnotationBuilder {
|
|
SqlSource sqlSource = buildSqlSource(selectKeyAnnotation, parameterTypeClass, languageDriver, null);
|
|
SqlSource sqlSource = buildSqlSource(selectKeyAnnotation, parameterTypeClass, languageDriver, null);
|
|
SqlCommandType sqlCommandType = SqlCommandType.SELECT;
|
|
SqlCommandType sqlCommandType = SqlCommandType.SELECT;
|
|
|
|
|
|
- assistant.addMappedStatement(id, sqlSource, statementType, sqlCommandType, fetchSize, timeout, parameterMap, parameterTypeClass, resultMap, resultTypeClass, resultSetTypeEnum,
|
|
|
|
- flushCache, useCache, false,
|
|
|
|
- keyGenerator, keyProperty, keyColumn, databaseId, languageDriver, null);
|
|
|
|
|
|
+ assistant.addMappedStatement(id, sqlSource, statementType, sqlCommandType, fetchSize, timeout, parameterMap,
|
|
|
|
+ parameterTypeClass, resultMap, resultTypeClass, resultSetTypeEnum, flushCache, useCache, false, keyGenerator,
|
|
|
|
+ keyProperty, keyColumn, databaseId, languageDriver, null, false);
|
|
|
|
|
|
id = assistant.applyCurrentNamespace(id, false);
|
|
id = assistant.applyCurrentNamespace(id, false);
|
|
|
|
|
|
@@ -614,7 +572,8 @@ public class MybatisMapperAnnotationBuilder extends MapperAnnotationBuilder {
|
|
Method method) {
|
|
Method method) {
|
|
if (annotation instanceof Select) {
|
|
if (annotation instanceof Select) {
|
|
return buildSqlSourceFromStrings(((Select) annotation).value(), parameterType, languageDriver);
|
|
return buildSqlSourceFromStrings(((Select) annotation).value(), parameterType, languageDriver);
|
|
- } else if (annotation instanceof Update) {
|
|
|
|
|
|
+ }
|
|
|
|
+ if (annotation instanceof Update) {
|
|
return buildSqlSourceFromStrings(((Update) annotation).value(), parameterType, languageDriver);
|
|
return buildSqlSourceFromStrings(((Update) annotation).value(), parameterType, languageDriver);
|
|
} else if (annotation instanceof Insert) {
|
|
} else if (annotation instanceof Insert) {
|
|
return buildSqlSourceFromStrings(((Insert) annotation).value(), parameterType, languageDriver);
|
|
return buildSqlSourceFromStrings(((Insert) annotation).value(), parameterType, languageDriver);
|
|
@@ -633,48 +592,65 @@ public class MybatisMapperAnnotationBuilder extends MapperAnnotationBuilder {
|
|
|
|
|
|
@SafeVarargs
|
|
@SafeVarargs
|
|
private final Optional<AnnotationWrapper> getAnnotationWrapper(Method method, boolean errorIfNoMatch,
|
|
private final Optional<AnnotationWrapper> getAnnotationWrapper(Method method, boolean errorIfNoMatch,
|
|
- Class<? extends Annotation>... targetTypes) {
|
|
|
|
|
|
+ Class<? extends Annotation>... targetTypes) {
|
|
return getAnnotationWrapper(method, errorIfNoMatch, Arrays.asList(targetTypes));
|
|
return getAnnotationWrapper(method, errorIfNoMatch, Arrays.asList(targetTypes));
|
|
}
|
|
}
|
|
|
|
|
|
private Optional<AnnotationWrapper> getAnnotationWrapper(Method method, boolean errorIfNoMatch,
|
|
private Optional<AnnotationWrapper> getAnnotationWrapper(Method method, boolean errorIfNoMatch,
|
|
- Collection<Class<? extends Annotation>> targetTypes) {
|
|
|
|
|
|
+ Collection<Class<? extends Annotation>> targetTypes) {
|
|
String databaseId = configuration.getDatabaseId();
|
|
String databaseId = configuration.getDatabaseId();
|
|
Map<String, AnnotationWrapper> statementAnnotations = targetTypes.stream()
|
|
Map<String, AnnotationWrapper> statementAnnotations = targetTypes.stream()
|
|
.flatMap(x -> Arrays.stream(method.getAnnotationsByType(x))).map(AnnotationWrapper::new)
|
|
.flatMap(x -> Arrays.stream(method.getAnnotationsByType(x))).map(AnnotationWrapper::new)
|
|
.collect(Collectors.toMap(AnnotationWrapper::getDatabaseId, x -> x, (existing, duplicate) -> {
|
|
.collect(Collectors.toMap(AnnotationWrapper::getDatabaseId, x -> x, (existing, duplicate) -> {
|
|
- throw new BuilderException(String.format("Detected conflicting annotations '%s' and '%s' on '%s'.",
|
|
|
|
- existing.getAnnotation(), duplicate.getAnnotation(),
|
|
|
|
- method.getDeclaringClass().getName() + StringPool.DOT + method.getName()));
|
|
|
|
|
|
+ throw new BuilderException(
|
|
|
|
+ String.format("Detected conflicting annotations '%s' and '%s' on '%s'.", existing.getAnnotation(),
|
|
|
|
+ duplicate.getAnnotation(), method.getDeclaringClass().getName() + "." + method.getName()));
|
|
}));
|
|
}));
|
|
AnnotationWrapper annotationWrapper = null;
|
|
AnnotationWrapper annotationWrapper = null;
|
|
if (databaseId != null) {
|
|
if (databaseId != null) {
|
|
annotationWrapper = statementAnnotations.get(databaseId);
|
|
annotationWrapper = statementAnnotations.get(databaseId);
|
|
}
|
|
}
|
|
if (annotationWrapper == null) {
|
|
if (annotationWrapper == null) {
|
|
- annotationWrapper = statementAnnotations.get(StringPool.EMPTY);
|
|
|
|
|
|
+ annotationWrapper = statementAnnotations.get("");
|
|
}
|
|
}
|
|
if (errorIfNoMatch && annotationWrapper == null && !statementAnnotations.isEmpty()) {
|
|
if (errorIfNoMatch && annotationWrapper == null && !statementAnnotations.isEmpty()) {
|
|
// Annotations exist, but there is no matching one for the specified databaseId
|
|
// Annotations exist, but there is no matching one for the specified databaseId
|
|
- throw new BuilderException(
|
|
|
|
- String.format(
|
|
|
|
- "Could not find a statement annotation that correspond a current database or default statement on method '%s.%s'. Current database id is [%s].",
|
|
|
|
- method.getDeclaringClass().getName(), method.getName(), databaseId));
|
|
|
|
|
|
+ throw new BuilderException(String.format(
|
|
|
|
+ "Could not find a statement annotation that correspond a current database or default statement on method '%s.%s'. Current database id is [%s].",
|
|
|
|
+ method.getDeclaringClass().getName(), method.getName(), databaseId));
|
|
}
|
|
}
|
|
return Optional.ofNullable(annotationWrapper);
|
|
return Optional.ofNullable(annotationWrapper);
|
|
}
|
|
}
|
|
|
|
|
|
- @Getter
|
|
|
|
- private class AnnotationWrapper {
|
|
|
|
|
|
+ public static Class<?> getMethodReturnType(String mapperFqn, String localStatementId) {
|
|
|
|
+ if (mapperFqn == null || localStatementId == null) {
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+ try {
|
|
|
|
+ Class<?> mapperClass = Resources.classForName(mapperFqn);
|
|
|
|
+ for (Method method : mapperClass.getMethods()) {
|
|
|
|
+ if (method.getName().equals(localStatementId) && canHaveStatement(method)) {
|
|
|
|
+ return getReturnType(method, mapperClass);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ } catch (ClassNotFoundException e) {
|
|
|
|
+ // No corresponding mapper interface which is OK
|
|
|
|
+ }
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private static class AnnotationWrapper {
|
|
private final Annotation annotation;
|
|
private final Annotation annotation;
|
|
private final String databaseId;
|
|
private final String databaseId;
|
|
private final SqlCommandType sqlCommandType;
|
|
private final SqlCommandType sqlCommandType;
|
|
|
|
+ private boolean dirtySelect;
|
|
|
|
|
|
AnnotationWrapper(Annotation annotation) {
|
|
AnnotationWrapper(Annotation annotation) {
|
|
this.annotation = annotation;
|
|
this.annotation = annotation;
|
|
if (annotation instanceof Select) {
|
|
if (annotation instanceof Select) {
|
|
databaseId = ((Select) annotation).databaseId();
|
|
databaseId = ((Select) annotation).databaseId();
|
|
sqlCommandType = SqlCommandType.SELECT;
|
|
sqlCommandType = SqlCommandType.SELECT;
|
|
|
|
+ dirtySelect = ((Select) annotation).affectData();
|
|
} else if (annotation instanceof Update) {
|
|
} else if (annotation instanceof Update) {
|
|
databaseId = ((Update) annotation).databaseId();
|
|
databaseId = ((Update) annotation).databaseId();
|
|
sqlCommandType = SqlCommandType.UPDATE;
|
|
sqlCommandType = SqlCommandType.UPDATE;
|
|
@@ -687,6 +663,7 @@ public class MybatisMapperAnnotationBuilder extends MapperAnnotationBuilder {
|
|
} else if (annotation instanceof SelectProvider) {
|
|
} else if (annotation instanceof SelectProvider) {
|
|
databaseId = ((SelectProvider) annotation).databaseId();
|
|
databaseId = ((SelectProvider) annotation).databaseId();
|
|
sqlCommandType = SqlCommandType.SELECT;
|
|
sqlCommandType = SqlCommandType.SELECT;
|
|
|
|
+ dirtySelect = ((SelectProvider) annotation).affectData();
|
|
} else if (annotation instanceof UpdateProvider) {
|
|
} else if (annotation instanceof UpdateProvider) {
|
|
databaseId = ((UpdateProvider) annotation).databaseId();
|
|
databaseId = ((UpdateProvider) annotation).databaseId();
|
|
sqlCommandType = SqlCommandType.UPDATE;
|
|
sqlCommandType = SqlCommandType.UPDATE;
|
|
@@ -707,5 +684,21 @@ public class MybatisMapperAnnotationBuilder extends MapperAnnotationBuilder {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ Annotation getAnnotation() {
|
|
|
|
+ return annotation;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ SqlCommandType getSqlCommandType() {
|
|
|
|
+ return sqlCommandType;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ String getDatabaseId() {
|
|
|
|
+ return databaseId;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ boolean isDirtySelect() {
|
|
|
|
+ return dirtySelect;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|