MyBatis的延迟加载,你知道是怎么实现的么?( 二 )


// 创建映射后的结果对象private Object createResultObject(ResultSetWrapper rsw, ResultMap resultMap, ResultLoaderMap lazyLoader, String columnPrefix) throws SQLException {// useConstructorMappings,表示是否使用构造方法创建该结果对象 。此处将其重置this.useConstructorMappings = false; // reset previous mapping resultfinal List<Class<?>> constructorArgTypes = new ArrayList<>(); // 记录使用的构造方法的参数类型的数组final List<Object> constructorArgs = new ArrayList<>(); // 记录使用的构造方法的参数值的数组// 创建映射后的结果对象Object resultObject = createResultObject(rsw, resultMap, constructorArgTypes, constructorArgs, columnPrefix);if (resultObject != null && !hasTypeHandlerForResultObject(rsw, resultMap.getType())) {// 如果有内嵌的查询,并且开启延迟加载,则创建结果对象的代理对象final List<ResultMapping> propertyMappings = resultMap.getPropertyResultMappings();for (ResultMapping propertyMapping : propertyMappings) {// issue gcode #109 && issue #149if (propertyMapping.getNestedQueryId() != null && propertyMapping.isLazy()) {// 创建延迟加载代理对象resultObject = configuration.getProxyFactory().createProxy(resultObject, lazyLoader, configuration, objectFactory, constructorArgTypes, constructorArgs);break;}}}// 判断是否使用构造方法创建该结果对象this.useConstructorMappings = resultObject != null && !constructorArgTypes.isEmpty(); // set current mapping resultreturn resultObject;}如果你想要在你的代码中验证延迟加载是否生效的话,那么有一个很简单的方法,开启日志的 SQL 打印功能,那么就可以直接验证你的延迟加载是否生效了 。
为什么需要延迟加载其实这也是延迟加载的优点,优点如下:
先从单表查询,需要时再从关联表去关联查询,??提?数据库性能,因为查询单表要比关联查询多张表速度要快 。
但是缺点也很明显:
有当需要用到数据时,才会进行数据库查询,这样在大批量数据查询时,因为查询工作也要消耗时间,所以可能造成?户等待时间变长,造成用户体验下降 。




推荐阅读