org.apache.ibatis.binding.MybatisCommonsMapperProxy Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of spring-data-mybatis Show documentation
Show all versions of spring-data-mybatis Show documentation
使用spring-data-commons实现mybatis应用
The newest version!
package org.apache.ibatis.binding;
import java.lang.invoke.MethodHandle;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;
import org.apache.commons.lang3.reflect.FieldUtils;
import org.apache.commons.lang3.reflect.MethodUtils;
import org.apache.ibatis.binding.MapperMethod.MethodSignature;
import org.apache.ibatis.reflection.ExceptionUtil;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.util.MapUtil;
import com.sneakxy.mybatis.commons.repository.query.parser.MybatisCommonsParamNameResolver;
/**
* @author 潜行的青衣
*/
public class MybatisCommonsMapperProxy extends MapperProxy {
/**
*
*/
private static final long serialVersionUID = -2465620582991346862L;
/**
* @param sqlSession
* @param mapperInterface
* @param methodCache
*/
public MybatisCommonsMapperProxy(SqlSession sqlSession, Class mapperInterface,
Map methodCache) {
super(sqlSession, mapperInterface, methodCache);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
try {
if (Object.class.equals(method.getDeclaringClass())) {
return method.invoke(this, args);
} else {
SqlSession sqlSession = (SqlSession) FieldUtils.readField(this, "sqlSession", true);
return cachedInvoker(method).invoke(proxy, method, args, sqlSession);
}
} catch (Throwable t) {
throw ExceptionUtil.unwrapThrowable(t);
}
}
@SuppressWarnings("unchecked")
private MapperMethodInvoker cachedInvoker(Method method) throws Throwable {
try {
Map methodCache = (Map) FieldUtils.readField(this,
"methodCache", true);
return MapUtil.computeIfAbsent(methodCache, method, m -> {
if (m.isDefault()) {
try {
Object privateLookupInMethod = FieldUtils.readStaticField(MapperProxy.class,
"privateLookupInMethod", true);
if (privateLookupInMethod == null) {
MethodHandle methodHandler = (MethodHandle) MethodUtils.invokeMethod(this,
"getMethodHandleJava8", method);
return new DefaultMethodInvoker(methodHandler);
} else {
MethodHandle methodHandler = (MethodHandle) MethodUtils.invokeMethod(this,
"getMethodHandleJava9", method);
return new DefaultMethodInvoker(methodHandler);
}
} catch (IllegalAccessException | InvocationTargetException
| NoSuchMethodException e) {
throw new RuntimeException(e);
}
} else {
try {
SqlSession sqlSession = (SqlSession) FieldUtils.readField(this, "sqlSession", true);
Class mapperInterface = (Class) FieldUtils.readField(this, "mapperInterface", true);
MapperMethod mapperMethod = new MapperMethod(mapperInterface, method, sqlSession.getConfiguration());
MethodSignature methodSignature = (MethodSignature) FieldUtils.readField(mapperMethod, "method", true);
MybatisCommonsParamNameResolver resolver = new MybatisCommonsParamNameResolver(sqlSession.getConfiguration(), method);
FieldUtils.writeField(methodSignature, "paramNameResolver", resolver, true);
return new PlainMethodInvoker(mapperMethod);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return null;
}
});
} catch (RuntimeException re) {
Throwable cause = re.getCause();
throw cause == null ? re : cause;
}
}
private static class PlainMethodInvoker implements MapperMethodInvoker {
private final MapperMethod mapperMethod;
public PlainMethodInvoker(MapperMethod mapperMethod) {
super();
this.mapperMethod = mapperMethod;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args, SqlSession sqlSession) throws Throwable {
return mapperMethod.execute(sqlSession, args);
}
}
private static class DefaultMethodInvoker implements MapperMethodInvoker {
private final MethodHandle methodHandle;
public DefaultMethodInvoker(MethodHandle methodHandle) {
super();
this.methodHandle = methodHandle;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args, SqlSession sqlSession) throws Throwable {
return methodHandle.bindTo(proxy).invokeWithArguments(args);
}
}
}