Skip to content
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
26 changes: 18 additions & 8 deletions src/main/java/org/apache/ibatis/binding/MapperMethod.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,7 @@
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.mapping.StatementType;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.ParamNameResolver;
import org.apache.ibatis.reflection.TypeParameterResolver;
import org.apache.ibatis.reflection.*;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
Expand Down Expand Up @@ -221,7 +219,7 @@ public static class SqlCommand {
public SqlCommand(Configuration configuration, Class<?> mapperInterface, Method method) {
final String methodName = method.getName();
final Class<?> declaringClass = method.getDeclaringClass();
MappedStatement ms = resolveMappedStatement(mapperInterface, methodName, declaringClass,
MappedStatement ms = resolveMappedStatement(mapperInterface, methodName, method.getParameterTypes(), declaringClass,
configuration);
if (ms == null) {
if(method.getAnnotation(Flush.class) != null){
Expand All @@ -248,17 +246,29 @@ public SqlCommandType getType() {
return type;
}

private MappedStatement resolveMappedStatement(Class<?> mapperInterface, String methodName,
private MappedStatement resolveMappedStatement(Class<?> mapperInterface, String methodName, Class<?>[] parameterTypes,
Class<?> declaringClass, Configuration configuration) {
String statementId = mapperInterface.getName() + "." + methodName;
if (configuration.hasStatement(statementId)) {
return configuration.getMappedStatement(statementId);

String params = ClassUtils.classesToString(parameterTypes);
String statementIdWithParameterTypes = statementId + ("".equals(params) ? "" : "#" + params);
MappedStatement mappedStatement = null;
try {
mappedStatement = configuration.getMappedStatement(statementIdWithParameterTypes);
} catch (Exception ex) {
//
}

if (mappedStatement != null && Arrays.deepEquals(mappedStatement.getParameterTypes(), parameterTypes)) {
return mappedStatement;
} else if ((configuration.hasStatement(statementId)) && (mappedStatement = configuration.getMappedStatement(statementId)) != null) {
return mappedStatement;
} else if (mapperInterface.equals(declaringClass)) {
return null;
}
for (Class<?> superInterface : mapperInterface.getInterfaces()) {
if (declaringClass.isAssignableFrom(superInterface)) {
MappedStatement ms = resolveMappedStatement(superInterface, methodName,
MappedStatement ms = resolveMappedStatement(superInterface, methodName, parameterTypes,
declaringClass, configuration);
if (ms != null) {
return ms;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,7 @@ public Discriminator buildDiscriminator(

public MappedStatement addMappedStatement(
String id,
Class<?>[] parameterTypes,
SqlSource sqlSource,
StatementType statementType,
SqlCommandType sqlCommandType,
Expand Down Expand Up @@ -276,6 +277,7 @@ public MappedStatement addMappedStatement(
boolean isSelect = sqlCommandType == SqlCommandType.SELECT;

MappedStatement.Builder statementBuilder = new MappedStatement.Builder(configuration, id, sqlSource, sqlCommandType)
.parameterTypes(parameterTypes)
.resource(resource)
.fetchSize(fetchSize)
.timeout(timeout)
Expand Down Expand Up @@ -503,7 +505,7 @@ public MappedStatement addMappedStatement(
String databaseId,
LanguageDriver lang) {
return addMappedStatement(
id, sqlSource, statementType, sqlCommandType, fetchSize, timeout,
id, null,sqlSource, statementType, sqlCommandType, fetchSize, timeout,
parameterMap, parameterType, resultMap, resultType, resultSetType,
flushCache, useCache, resultOrdered, keyGenerator, keyProperty,
keyColumn, databaseId, lang, null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,7 @@ void parseStatement(Method method) {

assistant.addMappedStatement(
mappedStatementId,
method.getParameterTypes(),
sqlSource,
statementType,
sqlCommandType,
Expand Down Expand Up @@ -652,7 +653,7 @@ private KeyGenerator handleSelectKeyAnnotation(SelectKey selectKeyAnnotation, St
SqlSource sqlSource = buildSqlSourceFromStrings(selectKeyAnnotation.statement(), parameterTypeClass, languageDriver);
SqlCommandType sqlCommandType = SqlCommandType.SELECT;

assistant.addMappedStatement(id, sqlSource, statementType, sqlCommandType, fetchSize, timeout, parameterMap, parameterTypeClass, resultMap, resultTypeClass, resultSetTypeEnum,
assistant.addMappedStatement(id, new Class<?>[]{parameterTypeClass}, sqlSource, statementType, sqlCommandType, fetchSize, timeout, parameterMap, parameterTypeClass, resultMap, resultTypeClass, resultSetTypeEnum,
flushCache, useCache, false,
keyGenerator, keyProperty, keyColumn, null, languageDriver, null);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,21 @@
*/
package org.apache.ibatis.builder.xml;

import java.util.List;
import java.util.Locale;

import org.apache.ibatis.builder.BaseBuilder;
import org.apache.ibatis.builder.MapperBuilderAssistant;
import org.apache.ibatis.executor.keygen.Jdbc3KeyGenerator;
import org.apache.ibatis.executor.keygen.KeyGenerator;
import org.apache.ibatis.executor.keygen.NoKeyGenerator;
import org.apache.ibatis.executor.keygen.SelectKeyGenerator;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.ResultSetType;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.mapping.SqlSource;
import org.apache.ibatis.mapping.StatementType;
import org.apache.ibatis.mapping.*;
import org.apache.ibatis.parsing.XNode;
import org.apache.ibatis.reflection.ClassUtils;
import org.apache.ibatis.scripting.LanguageDriver;
import org.apache.ibatis.session.Configuration;

import java.util.List;
import java.util.Locale;

/**
* @author Clinton Begin
*/
Expand Down Expand Up @@ -106,12 +103,29 @@ public void parseStatementNode() {
? Jdbc3KeyGenerator.INSTANCE : NoKeyGenerator.INSTANCE;
}

builderAssistant.addMappedStatement(id, sqlSource, statementType, sqlCommandType,
builderAssistant.addMappedStatement(id, getParameterTypes(id), sqlSource, statementType, sqlCommandType,
fetchSize, timeout, parameterMap, parameterTypeClass, resultMap, resultTypeClass,
resultSetTypeEnum, flushCache, useCache, resultOrdered,
keyGenerator, keyProperty, keyColumn, databaseId, langDriver, resultSets);
}

private Class<?>[] getParameterTypes(String id) {
int index = id.indexOf('#');
if (index <= 0 || id.length() == 2) {
return new Class[]{};
}
String types = id.substring(index + 1).trim();
if (types.length() == 0) {
return new Class[]{};
}
String[] classTypeNames = types.split(",");
Class<?>[] classes = new Class<?>[classTypeNames.length];
for (int i = 0; i < classTypeNames.length; i++) {
classes[i] = ClassUtils.getClassByName(classTypeNames[i]);
}
return classes;
}

private void processSelectKeyNodes(String id, Class<?> parameterTypeClass, LanguageDriver langDriver) {
List<XNode> selectKeyNodes = context.evalNodes("selectKey");
if (configuration.getDatabaseId() != null) {
Expand Down Expand Up @@ -153,7 +167,7 @@ private void parseSelectKeyNode(String id, XNode nodeToHandle, Class<?> paramete
SqlSource sqlSource = langDriver.createSqlSource(configuration, nodeToHandle, parameterTypeClass);
SqlCommandType sqlCommandType = SqlCommandType.SELECT;

builderAssistant.addMappedStatement(id, sqlSource, statementType, sqlCommandType,
builderAssistant.addMappedStatement(id, getParameterTypes(id), sqlSource, statementType, sqlCommandType,
fetchSize, timeout, parameterMap, parameterTypeClass, resultMap, resultTypeClass,
resultSetTypeEnum, flushCache, useCache, resultOrdered,
keyGenerator, keyProperty, keyColumn, databaseId, langDriver, null);
Expand Down
12 changes: 12 additions & 0 deletions src/main/java/org/apache/ibatis/mapping/MappedStatement.java
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ public final class MappedStatement {
private LanguageDriver lang;
private String[] resultSets;

private Class<?>[] parameterTypes;

MappedStatement() {
// constructor disabled
}
Expand Down Expand Up @@ -179,6 +181,12 @@ public Builder resulSets(String resultSet) {
mappedStatement.resultSets = delimitedStringToArray(resultSet);
return this;
}

public Builder parameterTypes(Class<?>[] parameterTypes){
mappedStatement.parameterTypes = parameterTypes;
return this;
}


public MappedStatement build() {
assert mappedStatement.configuration != null;
Expand Down Expand Up @@ -210,6 +218,10 @@ public String getId() {
return id;
}

public Class<?>[] getParameterTypes() {
return parameterTypes;
}

public boolean hasNestedResultMaps() {
return hasNestedResultMaps;
}
Expand Down
53 changes: 53 additions & 0 deletions src/main/java/org/apache/ibatis/reflection/ClassUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package org.apache.ibatis.reflection;

/**
* @author machunxiao
* @create 2018-07-19 22:32
*/
public class ClassUtils {

public static String classesToString(Class<?>[] classes) {
if (classes == null || classes.length == 0) {
return "";
}
StringBuilder builder = new StringBuilder();
for (int i = 0; i < classes.length; ) {
builder.append(classes[i].getName());
i++;
if (i < classes.length) {
builder.append(",");
}
}
return builder.toString();
}

public static Class<?> getClassByName(String className) {
if ("boolean".equals(className) || "bool".equals(className)) {
return boolean.class;
} else if ("byte".equalsIgnoreCase(className)) {
return byte.class;
} else if ("char".equalsIgnoreCase(className)) {
return char.class;
} else if ("short".equalsIgnoreCase(className)) {
return short.class;
} else if ("float".equalsIgnoreCase(className)) {
return float.class;
} else if ("int".equalsIgnoreCase(className)) {
return int.class;
} else if ("long".equalsIgnoreCase(className)) {
return long.class;
} else if ("double".equalsIgnoreCase(className)) {
return double.class;
} else if ("void".equalsIgnoreCase(className)){
return void.class;
} else {
try {
return Class.forName(className);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
}

private ClassUtils() {}
}
26 changes: 5 additions & 21 deletions src/main/java/org/apache/ibatis/session/Configuration.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,6 @@
*/
package org.apache.ibatis.session;

import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

import org.apache.ibatis.binding.MapperRegistry;
import org.apache.ibatis.builder.CacheRefResolver;
import org.apache.ibatis.builder.ResultMapResolver;
Expand All @@ -39,11 +29,7 @@
import org.apache.ibatis.datasource.jndi.JndiDataSourceFactory;
import org.apache.ibatis.datasource.pooled.PooledDataSourceFactory;
import org.apache.ibatis.datasource.unpooled.UnpooledDataSourceFactory;
import org.apache.ibatis.executor.BatchExecutor;
import org.apache.ibatis.executor.CachingExecutor;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.executor.ReuseExecutor;
import org.apache.ibatis.executor.SimpleExecutor;
import org.apache.ibatis.executor.*;
import org.apache.ibatis.executor.keygen.KeyGenerator;
import org.apache.ibatis.executor.loader.ProxyFactory;
import org.apache.ibatis.executor.loader.cglib.CglibProxyFactory;
Expand All @@ -63,15 +49,11 @@
import org.apache.ibatis.logging.nologging.NoLoggingImpl;
import org.apache.ibatis.logging.slf4j.Slf4jImpl;
import org.apache.ibatis.logging.stdout.StdOutImpl;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.Environment;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.ParameterMap;
import org.apache.ibatis.mapping.ResultMap;
import org.apache.ibatis.mapping.VendorDatabaseIdProvider;
import org.apache.ibatis.mapping.*;
import org.apache.ibatis.parsing.XNode;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.InterceptorChain;
import org.apache.ibatis.reflection.ClassUtils;
import org.apache.ibatis.reflection.DefaultReflectorFactory;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.ReflectorFactory;
Expand All @@ -91,6 +73,8 @@
import org.apache.ibatis.type.TypeHandler;
import org.apache.ibatis.type.TypeHandlerRegistry;

import java.util.*;

/**
* @author Clinton Begin
*/
Expand Down
10 changes: 10 additions & 0 deletions src/test/java/org/apache/ibatis/binding/BindingTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,16 @@ public void shouldfindThreeSpecificPosts() {
}
}

@Test
public void shouldfindOneSpecificPosts() {
try (SqlSession session = sqlSessionFactory.openSession()) {
BoundAuthorMapper mapper = session.getMapper(BoundAuthorMapper.class);
List<Post> posts = mapper.findThreeSpecificPosts(1);
assertEquals(1, posts.size());
assertEquals(1, posts.get(0).getId());
session.rollback();
}
}
@Test
public void shouldInsertAuthorWithSelectKey() {
try (SqlSession session = sqlSessionFactory.openSession()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ List<Post> findThreeSpecificPosts(@Param("one") int one,
@Param("two") int two,
int three);

List<Post> findThreeSpecificPosts(@Param("one") int one);

@Flush
List<BatchResult> flush();

Expand Down
5 changes: 5 additions & 0 deletions src/test/java/org/apache/ibatis/binding/BoundAuthorMapper.xml
Original file line number Diff line number Diff line change
Expand Up @@ -97,5 +97,10 @@
where id in (#{one},#{two},#{2})
</select>

<select id="findThreeSpecificPosts#int" parameterType="map" resultType="org.apache.ibatis.domain.blog.Post">
select * from post
where id = (#{one})
</select>


</mapper>
44 changes: 44 additions & 0 deletions src/test/java/org/apache/ibatis/reflection/ClassUtilsTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package org.apache.ibatis.reflection;

import org.junit.Assert;
import org.junit.Test;

/**
* @author machunxiao
* @create 2018-07-19 22:37
*/
public class ClassUtilsTest {

@Test
public void testClassesToString() {
Class<?>[] classes = new Class<?>[]{int.class, String.class};
String s = ClassUtils.classesToString(classes);
String original = "int,java.lang.String";
Assert.assertEquals(original, s);
}

@Test
public void testGetClassByName() {
String[] classNames = {"boolean", "bool", "byte", "short", "java.lang.Short", "int", "char", "float", "long", "double", String.class.getName(), "Void"};
Class<?>[] originalClasses = new Class<?>[]{
boolean.class,
boolean.class,
byte.class,
short.class,
Short.class,
int.class,
char.class,
float.class,
long.class,
double.class,
String.class,
void.class
};
Class<?>[] classes = new Class<?>[classNames.length];
for (int i = 0; i < classNames.length; i++) {
classes[i] = ClassUtils.getClassByName(classNames[i]);
}
Assert.assertArrayEquals(originalClasses, classes);
}

}