zoukankan      html  css  js  c++  java
  • mybatis-查询延迟加载功能

    SqlSession.getMapper -> 

       configuration.getMapper ->

          mapperRegistry.getMapper ->

            mapperProxyFactory.newInstance  返回mapper的代理对象 mapperProxy, 接口的查询、更新等方法通过动态代理技术由mapperProxy来代理执行。

    mapperProxy.invoke ->

         mapperMethod.execute ->   根据不同的sql类型执行 INSERT,UPDATE,DELETE,SELECT,FLUSH

          SELECT  : sqlSession.selectList  - >

                  configuration.getMappedStatement -> 

                            cachingExecutor.query ->   实际上委托 baseExecutor来执行的查询默认开启一级缓存,当开启 二级缓存的时候可以缓存查询结果

                                    baseExecutor.queryFromDatabase- >  

                                             RoutingStatementHandler.query -> 通过 configuration.newStatementHandler获得

                                                         DefaultResultSetHandler.handleResultSets ->   获取 mapperStatement即xml里定义的resultMap标签,根据resultMap组装查询返回结果,如果接口方法中没有ResultHandler参数,则使用DefaultResultHandler来处理结果

                                                            

     1 private Object getRowValue(ResultSetWrapper rsw, ResultMap resultMap) throws SQLException {
     2     final ResultLoaderMap lazyLoader = new ResultLoaderMap();
     3     //创建结果对象,如果有延迟加载的属性,则创建代理对象
     4     Object rowValue = createResultObject(rsw, resultMap, lazyLoader, null);
     5     if (rowValue != null && !hasTypeHandlerForResultObject(rsw, resultMap.getType())) {
     6       final MetaObject metaObject = configuration.newMetaObject(rowValue);
     7       boolean foundValues = this.useConstructorMappings;
     8      //自动映射结果对象属性,当XML里没有定义的时候也能自动映射
     9       if (shouldApplyAutomaticMappings(resultMap, false)) {
    10         foundValues = applyAutomaticMappings(rsw, resultMap, metaObject, null) || foundValues;
    11       }
    12      //有属性需要延迟加载的时候,调用lazyLoader.addLoader添加 延迟加载器
    13       foundValues = applyPropertyMappings(rsw, resultMap, metaObject, lazyLoader, null) || foundValues;
    14       foundValues = lazyLoader.size() > 0 || foundValues;
    15       rowValue = (foundValues || configuration.isReturnInstanceForEmptyRow()) ? rowValue : null;
    16     }
    17     return rowValue;
    18   }

      

     1 //查询嵌套的resultMap属性值  
     2 private Object getNestedQueryMappingValue(ResultSet rs, MetaObject metaResultObject, ResultMapping propertyMapping, ResultLoaderMap lazyLoader, String columnPrefix)
     3       throws SQLException {
     4     final String nestedQueryId = propertyMapping.getNestedQueryId();
     5     final String property = propertyMapping.getProperty();
     6     final MappedStatement nestedQuery = configuration.getMappedStatement(nestedQueryId);
     7     final Class<?> nestedQueryParameterType = nestedQuery.getParameterMap().getType();
     8     final Object nestedQueryParameterObject = prepareParameterForNestedQuery(rs, propertyMapping, nestedQueryParameterType, columnPrefix);
     9     Object value = null;
    10     if (nestedQueryParameterObject != null) {
    11       final BoundSql nestedBoundSql = nestedQuery.getBoundSql(nestedQueryParameterObject);
    12       final CacheKey key = executor.createCacheKey(nestedQuery, nestedQueryParameterObject, RowBounds.DEFAULT, nestedBoundSql);
    13       final Class<?> targetType = propertyMapping.getJavaType();
    14       if (executor.isCached(nestedQuery, key)) {
    15         executor.deferLoad(nestedQuery, metaResultObject, property, key, targetType);
    16         value = DEFERED;
    17       } else {
    18         final ResultLoader resultLoader = new ResultLoader(configuration, executor, nestedQuery, nestedQueryParameterObject, targetType, key, nestedBoundSql);
    19          //添加属性延迟加载器!!!!
    20         if (propertyMapping.isLazy()) {
    21           lazyLoader.addLoader(property, metaResultObject, resultLoader);
    22           value = DEFERED;
    23         } else {
    24           value = resultLoader.loadResult();
    25         }
    26       }
    27     }
    28     return value;
    29   }

    当返回结果对象查询延迟属性的时候触发动态代理

     1 @Override
     2     public Object invoke(Object enhanced, Method method, Method methodProxy, Object[] args) throws Throwable {
     3       final String methodName = method.getName();
     4       try {
     5         synchronized (lazyLoader) {
     6           if (WRITE_REPLACE_METHOD.equals(methodName)) {
     7             Object original;
     8             if (constructorArgTypes.isEmpty()) {
     9               original = objectFactory.create(type);
    10             } else {
    11               original = objectFactory.create(type, constructorArgTypes, constructorArgs);
    12             }
    13             PropertyCopier.copyBeanProperties(type, enhanced, original);
    14             if (lazyLoader.size() > 0) {
    15               return new JavassistSerialStateHolder(original, lazyLoader.getProperties(), objectFactory, constructorArgTypes, constructorArgs);
    16             } else {
    17               return original;
    18             }
    19           } else {
    20             //当查询的属性为延迟加载的属性时,LazyHolder
    21 进行延迟加载
    22             if (lazyLoader.size() > 0 && !FINALIZE_METHOD.equals(methodName)) {
    23               if (aggressive || lazyLoadTriggerMethods.contains(methodName)) {
    24                 lazyLoader.loadAll();
    25               } else if (PropertyNamer.isSetter(methodName)) {
    26                 final String property = PropertyNamer.methodToProperty(methodName);
    27                 lazyLoader.remove(property);
    28               } else if (PropertyNamer.isGetter(methodName)) {
    29                 final String property = PropertyNamer.methodToProperty(methodName);
    30                 if (lazyLoader.hasLoader(property)) {
    31                   //延迟加载
    32                   lazyLoader.load(property);
    33                 }
    34               }
    35             }
    36           }
    37         }
    38         return methodProxy.invoke(enhanced, args);
    39       } catch (Throwable t) {
    40         throw ExceptionUtil.unwrapThrowable(t);
    41       }
    42     }
    43   }

    至此,延迟加载逻辑结束!!

                                                             

                                                             

  • 相关阅读:
    Base64的解码和编码
    [WebService]代理类中对枚举类型的序列化
    Linq中的Where与SkipWhile
    Html 5中自定义data*特性
    实用TSQL之生成当前索引数据库中的外键上
    使用Post/Redirect/Get实现Asp.net防止表单重复提交
    用SquishIt最小化Css与Javascript文件
    Asp.net MVC 3 中 Unobtrusive javascript 与Ajax
    HTML5中custom data*特性与asp.net mvc 3 表单验证
    实现Asp.net MVC中AjaxOnly特性
  • 原文地址:https://www.cnblogs.com/ironroot/p/8522998.html
Copyright © 2011-2022 走看看