ResultSetHandler结果集处理
StatementHandler接口在执行完指定的select语句之后,会将查询得到的结果集交给ResultSetHandler完成映射处理。ResultSetHandler除了负责映射select语句查询得到的结果集,还会处理存储过程执行后的输出参数。
<!-- more -->
public interface ResultSetHandler {
// 处理结果集,生成相应的结果对象集合
<E> List<E> handleResultSets(Statement stmt) throws SQLException;
// 处理结果集,返回相应的游标对象
<E> Cursor<E> handleCursorResultSets(Statement stmt) throws SQLException;
// 处理存储过程的输出参数
void handleOutputParameters(CallableStatement cs) throws SQLException;
}
DefaultResultSetHandler
DefaultResultSetHandler是mybatis提供的resultSetHandler接口的唯一实现.
handleResultSets方法
处理select语句查询数据库得到的结果集.
public List<Object> handleResultSets(Statement stmt) throws SQLException {
ErrorContext.instance().activity("handling results").object(this.mappedStatement.getId());
// 用于保存映射结果集得到的结果对象
List<Object> multipleResults = new ArrayList();
int resultSetCount = 0;
// 获取第一个ResultSet对象(可能存在多个ResultSet,只获取第一个)
ResultSetWrapper rsw = this.getFirstResultSet(stmt);
// 获取在配置文件中配置的resultMap
List<ResultMap> resultMaps = this.mappedStatement.getResultMaps();
int resultMapCount = resultMaps.size();
// 检验结果映射的数量
this.validateResultMapsCount(rsw, resultMapCount);
// resultSetCount初始为0
while(rsw != null && resultMapCount > resultSetCount) {
// 取出ResultMap
ResultMap resultMap = (ResultMap)resultMaps.get(resultSetCount);
// 根据ResultMap中定义的映射规则对ResultSet进行映射,将映射的结果对象添加到multipleResults中
this.handleResultSet(rsw, resultMap, multipleResults, (ResultMapping)null);
// 获取下一个结果集
rsw = this.getNextResultSet(stmt);
this.cleanUpAfterHandlingResultSet();
++resultSetCount;
}
// 获取MappedStatement.resultSets属性,该属性仅对于多结果集的情况适用,该属性将列出语句执行后返回的结果集,并给每个结果集一个名称,名称使用逗号分隔
String[] resultSets = this.mappedStatement.getResultSets();
if (resultSets != null) {
while(rsw != null && resultSetCount < resultSets.length) {
ResultMapping parentMapping = (ResultMapping)this.nextResultMaps.get(resultSets[resultSetCount]);
if (parentMapping != null) {
String nestedResultMapId = parentMapping.getNestedResultMapId();
ResultMap resultMap = this.configuration.getResultMap(nestedResultMapId);
this.handleResultSet(rsw, resultMap, (List)null, parentMapping);
}
rsw = this.getNextResultSet(stmt);
this.cleanUpAfterHandlingResultSet();
++resultSetCount;
}
}
return this.collapseSingleResultList(multipleResults);
}
handleResultSet方法
handleResultSet该方法用来完成单个ResultSet的映射
private void handleResultSet(ResultSetWrapper rsw, ResultMap resultMap, List<Object> multipleResults, ResultMapping parentMapping) throws SQLException {
try {
if (parentMapping != null) {
// 处理多结果集中的嵌套映射
this.handleRowValues(rsw, resultMap, (ResultHandler)null, RowBounds.DEFAULT, parentMapping);
} else if (this.resultHandler == null) { // 没有指定ResultHandler,适用默认的
DefaultResultHandler defaultResultHandler = new DefaultResultHandler(this.objectFactory);
// 对ResultSet进行映射,将结果对象放到defaultResultHandler中暂存
this.handleRowValues(rsw, resultMap, defaultResultHandler, this.rowBounds, (ResultMapping)null);
multipleResults.add(defaultResultHandler.getResultList());
} else {
// 适用用户指定的resultHandler
this.handleRowValues(rsw, resultMap, this.resultHandler, this.rowBounds, (ResultMapping)null);
}
} finally {
this.closeResultSet(rsw.getResultSet());
}
}
public void handleRowValues(ResultSetWrapper rsw, ResultMap resultMap, ResultHandler<?> resultHandler, RowBounds rowBounds, ResultMapping parentMapping) throws SQLException {
// 存在嵌套结果集的情况
if (resultMap.hasNestedResultMaps()) {
this.ensureNoRowBounds();
this.checkResultHandler();
this.handleRowValuesForNestedResultMap(rsw, resultMap, resultHandler, rowBounds, parentMapping);
} else {
//不存在嵌套结果集的情况
this.handleRowValuesForSimpleResultMap(rsw, resultMap, resultHandler, rowBounds, parentMapping);
}
}
handleRowValuesForSimpleResultMap处理简单映射
private void handleRowValuesForSimpleResultMap(ResultSetWrapper rsw, ResultMap resultMap, ResultHandler<?> resultHandler, RowBounds rowBounds, ResultMapping parentMapping) throws SQLException {
DefaultResultContext<Object> resultContext = new DefaultResultContext();
ResultSet resultSet = rsw.getResultSet();
// 根据rowBounds中的offset值定位到指定的记录行,使用的是逻辑分页,如果数据量太大会导致内存溢出,最好实现分页方法而不是使用mybatis的默认分页
this.skipRows(resultSet, rowBounds);
// 检测是否还有需要映射的记录
while(this.shouldProcessMoreRows(resultContext, rowBounds) && !resultSet.isClosed() && resultSet.next()) { // 确定映射使用的ResultMap对象
ResultMap discriminatedResultMap = this.resolveDiscriminatedResultMap(resultSet, resultMap, (String)null);
// 对ResultSet中的一行记录进行映射
Object rowValue = this.getRowValue(rsw, discriminatedResultMap, (String)null);
this.storeObject(resultHandler, resultContext, rowValue, parentMapping, resultSet);
}
}
handleRowValuesForNestedResultMap处理嵌套映射
private void handleRowValuesForNestedResultMap(ResultSetWrapper rsw, ResultMap resultMap, ResultHandler<?> resultHandler, RowBounds rowBounds, ResultMapping parentMapping) throws SQLException {
DefaultResultContext<Object> resultContext = new DefaultResultContext();
ResultSet resultSet = rsw.getResultSet();
// 根据offset定位指定的记录行
this.skipRows(resultSet, rowBounds);
Object rowValue = this.previousRowValue;
// 检测是否能继续映射结果集中剩余的记录行
while(this.shouldProcessMoreRows(resultContext, rowBounds) && !resultSet.isClosed() && resultSet.next()) {
ResultMap discriminatedResultMap = this.resolveDiscriminatedResultMap(resultSet, resultMap, (String)null);
CacheKey rowKey = this.createRowKey(discriminatedResultMap, rsw, (String)null);
Object partialObject = this.nestedResultObjects.get(rowKey);
if (this.mappedStatement.isResultOrdered()) {
if (partialObject == null && rowValue != null) {
this.nestedResultObjects.clear();
this.storeObject(resultHandler, resultContext, rowValue, parentMapping, resultSet);
}
rowValue = this.getRowValue(rsw, discriminatedResultMap, rowKey, (String)null, partialObject);
} else {
rowValue = this.getRowValue(rsw, discriminatedResultMap, rowKey, (String)null, partialObject);
if (partialObject == null) {
this.storeObject(resultHandler, resultContext, rowValue, parentMapping, resultSet);
}
}
}
if (rowValue != null && this.mappedStatement.isResultOrdered() && this.shouldProcessMoreRows(resultContext, rowBounds)) {
this.storeObject(resultHandler, resultContext, rowValue, parentMapping, resultSet);
this.previousRowValue = null;
} else if (rowValue != null) {
this.previousRowValue = rowValue;
}
}
延迟加载
延迟加载表示:暂时不用的对象不会真正载入到内存中,直到真正需要使用该对象时,才会去执行数据库查询操作,将该对象加载到内存中。在Mybatis中,如果一个对象的某个属性需要延迟加载,那么在影射该属性时,会将该属性创建相应的代理对象并返回;当真正要使用延迟加载的属性时,会通过代理对象执行数据库加载操作,得到真正的数据。
延迟加载配置
- 属性在
<resultMap>
中的相应节点配置了fetchType属性,则按照fetchType属性决定是否延迟加载 未配置fetchType属性,则需要根据mybatis-config.xml配置文件中的lazyLoadingEnabled配置是否延时加载
<!-- 打开延时操作的开关 --> <settings name="lazyLoadingEnabled" value="true"/> <!-- 将积极加载改为按需加载 false为按需加载--> <settings name="aggressiveLazyLoading" value="false"/>
延迟加载原理
延迟加载使用动态代理实现的,由于映射的结果对象都为普通的类,没有使用接口,所以无法使用JDK代理
mybatis提供了两种为普通类动态生成代理对象的方式,为CGLIB方式和JAVASSIST方式
CGLIB
CGLIB采用字节码技术实现动态代理功能,原理是通过字节码技术为目标类生成子类,并在子类中采用方法拦截的方式拦截所有父类方法的调用,从而实现代理的功能。
public class CglibProxy implements MethodInterceptor {
private Enhancer enhancer = new Enhancer();
public Object getProxy(Class clazz){
// 指定代理类的父类
enhancer.setSuperclass(clazz);
// 设置Callback对象
enhancer.setCallback(this);
// 通过字节码技术动态创建子类实例
return enhancer.create();
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("前置处理");
Object result = methodProxy.invokeSuper(o,objects);
System.out.println("后置处理");
return result;
}
}
public class Test {
public void print(){
System.out.println("方法执行");
}
public static void main(String[] args) {
CglibProxy proxy = new CglibProxy();
Test proxyImp = (Test) proxy.getProxy(Test.class);
proxyImp.print();
}
}
Javassist
Javassist是一个开源的生成java字节码的类库,其主要优点在于简单、快速,直接使用Javassist提供的API就可以动态的修改类的结构,或是动态的生成类。
public class Test {
public static void main(String[] args) throws CannotCompileException, NotFoundException, IOException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
// 创建ClassPool
ClassPool classPool = ClassPool.getDefault();
// 生成类com.zhanghe.study.Gen
CtClass ctClass = classPool.makeClass("com.zhanghe.study.Gen");
StringBuffer body = null;
// 创建字段,指定字段类型、名称、所属类
CtField ctField = new CtField(classPool.get("java.lang.String"),"prop",ctClass);
// 设置为私有属性
ctField.setModifiers(Modifier.PRIVATE);
// 添加属性
ctClass.addField(ctField);
//getter/setter方法
ctClass.addMethod(CtNewMethod.getter("getProp",ctField));
ctClass.addMethod(CtNewMethod.setter("setProp",ctField));
// 创建execute方法 方法返回值、方法名称、方法入参。方法所属类
CtMethod ctMethod = new CtMethod(CtClass.voidType,"execute",new CtClass[]{},ctClass);
ctMethod.setModifiers(Modifier.PUBLIC);
body = new StringBuffer();
body.append("\n System.out.println(\"execute()方法执行\");");
body.append("\n");
// 设置方法体
ctMethod.setBody(body.toString());
ctClass.addMethod(ctMethod);
// 将类保存到文件中
ctClass.writeFile("./target/classes");
Class clazz = ctClass.toClass();
Object obj = clazz.newInstance();
Method method = obj.getClass().getMethod("setProp",String.class);
method.invoke(obj,"测试");
Method getMethod = obj.getClass().getMethod("getProp");
System.out.println(getMethod.invoke(obj));
Method exeMethod = obj.getClass().getMethod("execute");
exeMethod.invoke(obj);
}
}
public class JavassistMain {
public void test(){
System.out.println("执行");
}
}
public class JavassistTest {
public static ProxyFactory createProxy(){
ProxyFactory factory = new ProxyFactory();
factory.setSuperclass(JavassistMain.class);
// 设置拦截器
factory.setFilter(method -> {
if("test".equals(method.getName())){
return true;
}
return false;
});
return factory;
}
public static void main(String[] args) throws IllegalAccessException, InstantiationException {
ProxyFactory factory = createProxy();
Class clazz = factory.createClass();
Object obj = clazz.newInstance();
((ProxyObject)obj).setHandler(new MyMethodHandler());
((JavassistMain)obj).test();
}
}
public class MyMethodHandler implements MethodHandler {
@Override
/**
* self 生成的代理类
* method 原始的方法
* process 生成代理类的代理方法
* objects 方法入参
*/
public Object invoke(Object self, Method method, Method process, Object[] objects) throws Throwable {
System.out.println("前置处理");
Object obj = process.invoke(self,objects);
System.out.println("后置处理");
return obj;
}
}
ResultLoader
ResultLoader负责保存一次延迟加载操作所需的全部信息
public class ResultLoader {
protected final Configuration configuration;
protected final Executor executor;
protected final MappedStatement mappedStatement;
protected final Object parameterObject;
// 延迟加载得到的对象类型
protected final Class<?> targetType;
// 通过反射创建延迟加载对象
protected final ObjectFactory objectFactory;
protected final CacheKey cacheKey;
// 记录延迟执行的SQL语句以及相关配置信息
protected final BoundSql boundSql;
// 负责将延迟加载得到的结果对象转换为targetType类型的对象
protected final ResultExtractor resultExtractor;
protected final long creatorThreadId;
protected boolean loaded;
// 延迟加载得到的结果对象
protected Object resultObject;
public ResultLoader(Configuration config, Executor executor, MappedStatement mappedStatement, Object parameterObject, Class<?> targetType, CacheKey cacheKey, BoundSql boundSql) {
this.configuration = config;
this.executor = executor;
this.mappedStatement = mappedStatement;
this.parameterObject = parameterObject;
this.targetType = targetType;
this.objectFactory = this.configuration.getObjectFactory();
this.cacheKey = cacheKey;
this.boundSql = boundSql;
this.resultExtractor = new ResultExtractor(this.configuration, this.objectFactory);
this.creatorThreadId = Thread.currentThread().getId();
}
public Object loadResult() throws SQLException {
// 执行延迟加载,得到结果对象
List<Object> list = this.selectList();
// 将list集合转换为targetType指定类型的对象
this.resultObject = this.resultExtractor.extractObjectFromList(list, this.targetType);
return this.resultObject;
}
private <E> List<E> selectList() throws SQLException {
Executor localExecutor = this.executor;
// 检测调用该方法的线程是否为创建ResultLoader对象的线程、检测localExecutor是否关闭
if (Thread.currentThread().getId() != this.creatorThreadId || localExecutor.isClosed()) {
localExecutor = this.newExecutor();
}
List var2;
try {
// 执行查询操作,得到延迟加载的对象。
var2 = localExecutor.query(this.mappedStatement, this.parameterObject, RowBounds.DEFAULT, Executor.NO_RESULT_HANDLER, this.cacheKey, this.boundSql);
} finally {
if (localExecutor != this.executor) {
localExecutor.close(false);
}
}
return var2;
}
private Executor newExecutor() {
Environment environment = this.configuration.getEnvironment();
if (environment == null) {
throw new ExecutorException("ResultLoader could not load lazily. Environment was not configured.");
} else {
DataSource ds = environment.getDataSource();
if (ds == null) {
throw new ExecutorException("ResultLoader could not load lazily. DataSource was not configured.");
} else {
TransactionFactory transactionFactory = environment.getTransactionFactory();
Transaction tx = transactionFactory.newTransaction(ds, (TransactionIsolationLevel)null, false);
return this.configuration.newExecutor(tx, ExecutorType.SIMPLE);
}
}
}
public boolean wasNull() {
return this.resultObject == null;
}
}
ProxyFactory
public interface ProxyFactory {
default void setProperties(Properties properties) {
}
// 创建代理对象
Object createProxy(Object var1, ResultLoaderMap var2, Configuration var3, ObjectFactory var4, List<Class<?>> var5, List<Object> var6);
}
有两个子类,CglibProxyFactory和JavassistProxyFactory
CglibProxyFactory
public class CglibProxyFactory implements ProxyFactory {
private static final String FINALIZE_METHOD = "finalize";
private static final String WRITE_REPLACE_METHOD = "writeReplace";
public CglibProxyFactory() {
try {
Resources.classForName("net.sf.cglib.proxy.Enhancer");
} catch (Throwable var2) {
throw new IllegalStateException("Cannot enable lazy loading because CGLIB is not available. Add CGLIB to your classpath.", var2);
}
}
public Object createProxy(Object target, ResultLoaderMap lazyLoader, Configuration configuration, ObjectFactory objectFactory, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
return CglibProxyFactory.EnhancedResultObjectProxyImpl.createProxy(target, lazyLoader, configuration, objectFactory, constructorArgTypes, constructorArgs);
}
public Object createDeserializationProxy(Object target, Map<String, LoadPair> unloadedProperties, ObjectFactory objectFactory, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
return CglibProxyFactory.EnhancedDeserializationProxyImpl.createProxy(target, unloadedProperties, objectFactory, constructorArgTypes, constructorArgs);
}
static Object crateProxy(Class<?> type, Callback callback, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
Enhancer enhancer = new Enhancer();
enhancer.setCallback(callback);
enhancer.setSuperclass(type);
try {
type.getDeclaredMethod("writeReplace");
} catch (NoSuchMethodException var8) {
enhancer.setInterfaces(new Class[]{WriteReplaceInterface.class});
} catch (SecurityException var9) {
}
Object enhanced;
if (constructorArgTypes.isEmpty()) {
enhanced = enhancer.create();
} else {
Class<?>[] typesArray = (Class[])constructorArgTypes.toArray(new Class[constructorArgTypes.size()]);
Object[] valuesArray = constructorArgs.toArray(new Object[constructorArgs.size()]);
enhanced = enhancer.create(typesArray, valuesArray);
}
return enhanced;
}
private static class EnhancedDeserializationProxyImpl extends AbstractEnhancedDeserializationProxy implements MethodInterceptor {
private EnhancedDeserializationProxyImpl(Class<?> type, Map<String, LoadPair> unloadedProperties, ObjectFactory objectFactory, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
super(type, unloadedProperties, objectFactory, constructorArgTypes, constructorArgs);
}
public static Object createProxy(Object target, Map<String, LoadPair> unloadedProperties, ObjectFactory objectFactory, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
Class<?> type = target.getClass();
CglibProxyFactory.EnhancedDeserializationProxyImpl callback = new CglibProxyFactory.EnhancedDeserializationProxyImpl(type, unloadedProperties, objectFactory, constructorArgTypes, constructorArgs);
Object enhanced = CglibProxyFactory.crateProxy(type, callback, constructorArgTypes, constructorArgs);
PropertyCopier.copyBeanProperties(type, target, enhanced);
return enhanced;
}
public Object intercept(Object enhanced, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object o = super.invoke(enhanced, method, args);
return o instanceof AbstractSerialStateHolder ? o : methodProxy.invokeSuper(o, args);
}
protected AbstractSerialStateHolder newSerialStateHolder(Object userBean, Map<String, LoadPair> unloadedProperties, ObjectFactory objectFactory, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
return new CglibSerialStateHolder(userBean, unloadedProperties, objectFactory, constructorArgTypes, constructorArgs);
}
}
private static class EnhancedResultObjectProxyImpl implements MethodInterceptor {
private final Class<?> type;
private final ResultLoaderMap lazyLoader;
private final boolean aggressive;
private final Set<String> lazyLoadTriggerMethods;
private final ObjectFactory objectFactory;
private final List<Class<?>> constructorArgTypes;
private final List<Object> constructorArgs;
private EnhancedResultObjectProxyImpl(Class<?> type, ResultLoaderMap lazyLoader, Configuration configuration, ObjectFactory objectFactory, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
this.type = type;
this.lazyLoader = lazyLoader;
this.aggressive = configuration.isAggressiveLazyLoading();
this.lazyLoadTriggerMethods = configuration.getLazyLoadTriggerMethods();
this.objectFactory = objectFactory;
this.constructorArgTypes = constructorArgTypes;
this.constructorArgs = constructorArgs;
}
public static Object createProxy(Object target, ResultLoaderMap lazyLoader, Configuration configuration, ObjectFactory objectFactory, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
Class<?> type = target.getClass();
CglibProxyFactory.EnhancedResultObjectProxyImpl callback = new CglibProxyFactory.EnhancedResultObjectProxyImpl(type, lazyLoader, configuration, objectFactory, constructorArgTypes, constructorArgs);
Object enhanced = CglibProxyFactory.crateProxy(type, callback, constructorArgTypes, constructorArgs);
PropertyCopier.copyBeanProperties(type, target, enhanced);
return enhanced;
}
public Object intercept(Object enhanced, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
String methodName = method.getName();
try {
synchronized(this.lazyLoader) {
if ("writeReplace".equals(methodName)) {
Object original;
if (this.constructorArgTypes.isEmpty()) {
original = this.objectFactory.create(this.type);
} else {
original = this.objectFactory.create(this.type, this.constructorArgTypes, this.constructorArgs);
}
PropertyCopier.copyBeanProperties(this.type, enhanced, original);
if (this.lazyLoader.size() > 0) {
return new CglibSerialStateHolder(original, this.lazyLoader.getProperties(), this.objectFactory, this.constructorArgTypes, this.constructorArgs);
}
return original;
}
// 是否有延迟加载属性
if (this.lazyLoader.size() > 0 && !"finalize".equals(methodName)) {
// aggressiveLazyLoading配置为true,或者调用的方法在lazyLoadTriggerMethods中,将全部属性加载完
if (!this.aggressive && !this.lazyLoadTriggerMethods.contains(methodName)) {
String property;
if (PropertyNamer.isSetter(methodName)) {
property = PropertyNamer.methodToProperty(methodName);
this.lazyLoader.remove(property);
}
// 调用了某属性的getter方法,现获取该属性的名称
else if (PropertyNamer.isGetter(methodName)) {
property = PropertyNamer.methodToProperty(methodName);
// 该属性是否为延迟加载属性
if (this.lazyLoader.hasLoader(property)) {
// 触发该属性的延迟加载操作
this.lazyLoader.load(property);
}
}
} else {
this.lazyLoader.loadAll();
}
}
}
return methodProxy.invokeSuper(enhanced, args);
} catch (Throwable var10) {
throw ExceptionUtil.unwrapThrowable(var10);
}
}
}
}
JavassistProxyFactory
public class JavassistProxyFactory implements ProxyFactory {
private static final String FINALIZE_METHOD = "finalize";
private static final String WRITE_REPLACE_METHOD = "writeReplace";
public JavassistProxyFactory() {
try {
Resources.classForName("org.apache.ibatis.javassist.util.proxy.ProxyFactory");
} catch (Throwable var2) {
throw new IllegalStateException("Cannot enable lazy loading because Javassist is not available. Add Javassist to your classpath.", var2);
}
}
public Object createProxy(Object target, ResultLoaderMap lazyLoader, Configuration configuration, ObjectFactory objectFactory, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
return JavassistProxyFactory.EnhancedResultObjectProxyImpl.createProxy(target, lazyLoader, configuration, objectFactory, constructorArgTypes, constructorArgs);
}
public Object createDeserializationProxy(Object target, Map<String, LoadPair> unloadedProperties, ObjectFactory objectFactory, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
return JavassistProxyFactory.EnhancedDeserializationProxyImpl.createProxy(target, unloadedProperties, objectFactory, constructorArgTypes, constructorArgs);
}
static Object crateProxy(Class<?> type, MethodHandler callback, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
org.apache.ibatis.javassist.util.proxy.ProxyFactory enhancer = new org.apache.ibatis.javassist.util.proxy.ProxyFactory();
enhancer.setSuperclass(type);
try {
type.getDeclaredMethod("writeReplace");
} catch (NoSuchMethodException var10) {
enhancer.setInterfaces(new Class[]{WriteReplaceInterface.class});
} catch (SecurityException var11) {
}
Class<?>[] typesArray = (Class[])constructorArgTypes.toArray(new Class[constructorArgTypes.size()]);
Object[] valuesArray = constructorArgs.toArray(new Object[constructorArgs.size()]);
Object enhanced;
try {
enhanced = enhancer.create(typesArray, valuesArray);
} catch (Exception var9) {
throw new ExecutorException("Error creating lazy proxy. Cause: " + var9, var9);
}
((Proxy)enhanced).setHandler(callback);
return enhanced;
}
private static class EnhancedDeserializationProxyImpl extends AbstractEnhancedDeserializationProxy implements MethodHandler {
private EnhancedDeserializationProxyImpl(Class<?> type, Map<String, LoadPair> unloadedProperties, ObjectFactory objectFactory, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
super(type, unloadedProperties, objectFactory, constructorArgTypes, constructorArgs);
}
public static Object createProxy(Object target, Map<String, LoadPair> unloadedProperties, ObjectFactory objectFactory, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
Class<?> type = target.getClass();
JavassistProxyFactory.EnhancedDeserializationProxyImpl callback = new JavassistProxyFactory.EnhancedDeserializationProxyImpl(type, unloadedProperties, objectFactory, constructorArgTypes, constructorArgs);
Object enhanced = JavassistProxyFactory.crateProxy(type, callback, constructorArgTypes, constructorArgs);
PropertyCopier.copyBeanProperties(type, target, enhanced);
return enhanced;
}
public Object invoke(Object enhanced, Method method, Method methodProxy, Object[] args) throws Throwable {
Object o = super.invoke(enhanced, method, args);
return o instanceof AbstractSerialStateHolder ? o : methodProxy.invoke(o, args);
}
protected AbstractSerialStateHolder newSerialStateHolder(Object userBean, Map<String, LoadPair> unloadedProperties, ObjectFactory objectFactory, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
return new JavassistSerialStateHolder(userBean, unloadedProperties, objectFactory, constructorArgTypes, constructorArgs);
}
}
private static class EnhancedResultObjectProxyImpl implements MethodHandler {
private final Class<?> type;
private final ResultLoaderMap lazyLoader;
private final boolean aggressive;
private final Set<String> lazyLoadTriggerMethods;
private final ObjectFactory objectFactory;
private final List<Class<?>> constructorArgTypes;
private final List<Object> constructorArgs;
private EnhancedResultObjectProxyImpl(Class<?> type, ResultLoaderMap lazyLoader, Configuration configuration, ObjectFactory objectFactory, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
this.type = type;
this.lazyLoader = lazyLoader;
this.aggressive = configuration.isAggressiveLazyLoading();
this.lazyLoadTriggerMethods = configuration.getLazyLoadTriggerMethods();
this.objectFactory = objectFactory;
this.constructorArgTypes = constructorArgTypes;
this.constructorArgs = constructorArgs;
}
public static Object createProxy(Object target, ResultLoaderMap lazyLoader, Configuration configuration, ObjectFactory objectFactory, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
Class<?> type = target.getClass();
JavassistProxyFactory.EnhancedResultObjectProxyImpl callback = new JavassistProxyFactory.EnhancedResultObjectProxyImpl(type, lazyLoader, configuration, objectFactory, constructorArgTypes, constructorArgs);
Object enhanced = JavassistProxyFactory.crateProxy(type, callback, constructorArgTypes, constructorArgs);
PropertyCopier.copyBeanProperties(type, target, enhanced);
return enhanced;
}
public Object invoke(Object enhanced, Method method, Method methodProxy, Object[] args) throws Throwable {
String methodName = method.getName();
try {
synchronized(this.lazyLoader) {
if ("writeReplace".equals(methodName)) {
Object original;
if (this.constructorArgTypes.isEmpty()) {
original = this.objectFactory.create(this.type);
} else {
original = this.objectFactory.create(this.type, this.constructorArgTypes, this.constructorArgs);
}
PropertyCopier.copyBeanProperties(this.type, enhanced, original);
if (this.lazyLoader.size() > 0) {
return new JavassistSerialStateHolder(original, this.lazyLoader.getProperties(), this.objectFactory, this.constructorArgTypes, this.constructorArgs);
}
return original;
}
if (this.lazyLoader.size() > 0 && !"finalize".equals(methodName)) {
if (!this.aggressive && !this.lazyLoadTriggerMethods.contains(methodName)) {
String property;
if (PropertyNamer.isSetter(methodName)) {
property = PropertyNamer.methodToProperty(methodName);
this.lazyLoader.remove(property);
} else if (PropertyNamer.isGetter(methodName)) {
property = PropertyNamer.methodToProperty(methodName);
if (this.lazyLoader.hasLoader(property)) {
this.lazyLoader.load(property);
}
}
} else {
this.lazyLoader.loadAll();
}
}
}
return methodProxy.invoke(enhanced, args);
} catch (Throwable var10) {
throw ExceptionUtil.unwrapThrowable(var10);
}
}
}
}
https://zhhll.icu/2020/框架/mybatis/组件分析/9.mybatis之ResultSetHandler结果集处理/
本文由mdnice多平台发布
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。