com.github.nomou.mybatis.builder.spi.Parameters Maven / Gradle / Ivy
package com.github.nomou.mybatis.builder.spi;
import com.github.nomou.mybatis.util.Collections2;
import freework.reflect.Types;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.binding.MapperMethod;
import org.apache.ibatis.reflection.ParamNameResolver;
import org.apache.ibatis.session.Configuration;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.*;
public class Parameters implements Iterable {
/**
* @see org.apache.ibatis.reflection.ParamNameResolver#GENERIC_NAME_PREFIX
*/
public static final String GENERIC_NAME_PREFIX = "param";
private final Method declaringMethod;
private final List parameters;
private final boolean annotated;
private final Configuration configuration;
public Parameters(final Method declaringMethod, final Class> runtimeType, final Configuration configuration, final Class>... excludes) {
this(declaringMethod, runtimeType, configuration, Collections2.newImmutableSet(excludes));
}
public Parameters(final Method declaringMethod, final Class> runtimeType, final Configuration configuration, final Set> excludeClasses) {
boolean annotated = false;
final Type[] parameterTypes = declaringMethod.getGenericParameterTypes();
final List parameters = new ArrayList(parameterTypes.length);
for (int index = 0; index < parameterTypes.length; index++) {
Class> parameterClass;
final Type parameterType = Types.resolveType(parameterTypes[index], runtimeType);
if (parameterType instanceof Class>) {
parameterClass = (Class>) parameterType;
} else if (parameterType instanceof ParameterizedType) {
parameterClass = (Class>) ((ParameterizedType) parameterType).getRawType();
} else {
parameterClass = declaringMethod.getParameterTypes()[index];
}
if (isExcludeType(parameterClass, excludeClasses)) {
continue;
}
/*-
* @see org.apache.ibatis.reflection.ParamNameResolver.ParamNameResolver
*/
final Parameter parameter = new Parameter(declaringMethod, index, parameterType, configuration.isUseActualParamName());
if (null != parameter.getAnnotation(Param.class)) {
annotated = true;
}
parameters.add(parameter);
}
this.declaringMethod = declaringMethod;
this.parameters = Collections.unmodifiableList(parameters);
this.annotated = annotated;
this.configuration = configuration;
}
public int size() {
return parameters.size();
}
public boolean isEmpty() {
return parameters.isEmpty();
}
public Method getDeclaringMethod() {
return declaringMethod;
}
public List getParameters() {
return Collections.unmodifiableList(parameters);
}
/**
* 获取所有参数名称, 如果参数名称无法获取但'required=true'则使用其在当前参数队列中的索引作为其名称.
*
* @param required 是否必须
* @return 参数名称
*/
public String[] getParameterNames(final boolean required) {
final String[] names = new String[parameters.size()];
for (int index = 0; index < names.length; index++) {
final String name = parameters.get(index).getName();
names[index] = null != name || !required ? name : String.valueOf(index);
}
return names;
}
public Class>[] getParameterTypes() {
final Class>[] types = new Class>[parameters.size()];
for (int i = 0; i < types.length; i++) {
types[i] = parameters.get(i).getType();
}
return types;
}
/**
* 获取mybatis调用时的参数类型.
*
* 对于mapper接口中方法的非特殊参数, mybatis会转换为一个参数.
*
* @return mybatis 调用时的参数类型, 如果没有参数返回null, 只有一个参数返回参数类型, 有多个参数返回{@link MapperMethod.ParamMap}
* @see org.apache.ibatis.builder.annotation.MapperAnnotationBuilder#getParameterType(Method)
* @see org.apache.ibatis.reflection.ParamNameUtil
*/
public Class> getInvokeParameterType() {
Class> invokeParameterType = null;
final Class>[] parameterTypes = getParameterTypes();
if (1 == parameterTypes.length) {
invokeParameterType = parameterTypes[0];
} else if (1 < parameterTypes.length) {
invokeParameterType = MapperMethod.ParamMap.class;
}
return invokeParameterType;
}
/**
* 获取调用mapper时传递的参数在内部调用时使用的参数对象.
*
* @param args 实际传递的参数
* @return 调用时使用的参数对象
*/
public Object getInvokeParameterObject(final Object[] args) {
final List parameterNames = Arrays.asList(getParameterNames(true));
final List parameters = getParameters();
if (null == args || 0 == parameterNames.size()) {
return null;
} else if (!annotated && 1 == parameterNames.size()) {
return args[parameters.iterator().next().getIndex()];
} else {
final Map paramsMap = new MapperMethod.ParamMap
© 2015 - 2025 Weber Informatics LLC | Privacy Policy