• Mybatis mark 勿看


    Mybatis底层原理总结(一)

    2018年01月11日 11:51:06
    阅读数:2668

    本文适合对Mybatis有一定了解的。

    1. Mybatis 读取XML配置文件后会将内容放在一个Configuration类中,Configuration类会存在整个Mybatis生命周期,以便重复读取。SqlSessionFactoryBuilder会读取Configuration类中信息创建SqlSessionFactory。


    2. Mybatis中SqlSessionFactiory、SqlSession等都为接口,Mybatis默认使用的实现类为DefaultSqlSessionFactory和DefaultSqlSession类。


    3. SqlSession用途主要有两种

    ①. 获取对应的Mapper,让映射器通过命名空间和方法名称找到对应的SQL,发送给数据库执行后返回结果。

    ②. 直接使用SqlSession,通过命名信息去执行SQL返回结果,该方式是IBatis版本留下的,SqlSession通过Update、Select、Insert、Delete等方法操作。

    针对Mapper方式,Mybatis底层利用JDK动态代理技术实现该接口,底层最后还是使用的IBatis中SqlSession通过Update、Select、Insert、Delete等方法操作。


    4.关于对象的生命周期:

    ①. SqlSessionFactoryBuilder的作用是创建SqlSessionFactiory,在创建完成后就会被回收,所以它的生命周期只存在于局部方法。

    ②.SqlSessionFactiory是单例的,作用就是创建SqlSession,每次访问数据库都需要一个SqlSession,所以SqlSessionFactiory的生命周期是贯穿整个Mybatis生命周期的,SqlSessionFactiory采用单例的原因是减少数据库连接资源。

    ③. SqlSession是一个会话,类似于jdbc的connection,它的生命周期是在请求数据库处理事务过程中,他是一个线程不安全的对象。多线程操作时因多注意他的隔离级别和数据库锁等。SqlSession使用需及时关闭。

    ④. Mapper是一个接口,它的作用是发送SQL,返回结果,因此他的生命周期不会大于SqlSession


    5. 关于SqlSessionFactory的创建,Mybatis采用构造模式来完成创建。

    第一步:XMLConfigBuilder解析XML配置,读出配置参数,存入Configuration类中。

    第二步:Configuration类创建SqlSessionFactory。(DefaultSqlSessionFactory的构造函数传入Configuration类

    SqlSessionFactoryBuilder.builder(inputStream) inputStream为读取配置文件的流;该方法.builder中的主要内容: 

    XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties);
    SqlSessionFactory localSqlSessionFactory = build(parser.parse());

    build(parser.parse())方法实则为:

    public SqlSessionFactory build(Configuration config) {
       return new DefaultSqlSessionFactory(config);
     }


    6. 映射器由MappedStatement、SqlSource、BoundSql三部分组成。

    ①. MappedStatement,它保存着映射器的一个节点(select|update|insert|delete)。包括许多我们配置的SQL、SQL的ID、缓存信息、resultMap、parameterType、resultType等配置内容。

    ②. SqlSource,它提供BoundSql对象。是MappedStatement的一个属性。、

    ③. BoundSql,它是建立SQL和参数的地方,常用的三个属性:SQL、parameterObject、parameterMappings;

    parameterObject就是我们传入的参数;

    parameterMappings实则是List<ParameterMapping>,ParameterMapping描述了我们的参数,包括属性、名称、表达式、javaType、jdbcType、typeHandler等重要信息,通过它实现参数和SQL的结合,以便PreparedStatement能够通过它找到parameterObject对象的属性并设置参数。

    SQL则为我们写的SQL语句。


    Mybatis之工作原理 https://blog.csdn.net/u014297148/article/details/78696096

    2017年12月03日 16:37:12
    阅读数:28566

    1.Mybatis的架构

    1.1 Mybatis的框架分层

    这里写图片描述

    1.2 MyBatis的实现原理

    mybatis底层还是采用原生jdbc来对数据库进行操作的,只是通过 SqlSessionFactory,SqlSession Executor,StatementHandler,ParameterHandler,ResultHandler和TypeHandler等几个处理器封装了这些过程

         执行器:Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)    参数处理器: ParameterHandler (getParameterObject, setParameters)    结构处理器 ResultSetHandler (handleResultSets, handleOutputParameters)     sql查询处理器:StatementHandler (prepare, parameterize, batch, update, query) 
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    其中StatementHandler用通过ParameterHandler与ResultHandler分别进行参数预编译 与结果处理。而ParameterHandler与ResultHandler都使用TypeHandler进行映射。如下图: 
    这里写图片描述

    2.Mybatis工作过程

    通过读mybatis的源码进行分析mybatis的执行操作的整个过程,我们通过debug调试就可以知道Mybatis每一步做了什么事,我先把debug每一步结果 截图,然后在分析这个流程。 
    第一步:读取配置文件,形成InputStream

    2.1 创建SqlSessionFacotry的过程

    这里写图片描述 
    从debug调试看出 返回的 sqlSessionFactory 是DefaultSesssionFactory类型的,但是configuration此时已经被初始化了。查看源码后画如下创建DefaultSessionFactory的时序图: 
    这里写图片描述

    2.2 创建SqlSession的过程

    这里写图片描述 
    从debug调试 看出SqlSessinoFactory.openSession() 返回的sqlSession是 DefaultSession类型的,此SqlSession里包含一个Configuration的对象,和一个Executor对象。查看源码后画如下创建DefaultSession的时序图:

    这里写图片描述

    2.3 创建Mapper的过程

    这里写图片描述 
    从debug调试可以看出,mapper是一个Mapper代理对象,而且初始化了Configuration对象,Executor的对象。查看源码后画如下创建Mapper的时序图: 
    这里写图片描述

    2.4 执行CRUD过程

    2.4.1 以select为例查看各步执行的源码

    1.mapper.selectEmployeeList()其实是MapperProxy执行invoke方法,此方法显示是判断Method的方法是不是Object的toString等方法如果不是就执行MapperMethod

     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // 判断Method的方法是不是Object的toString等方法      if(Object.class.equals(method.getDeclaringClass())) {             try {                 return method.invoke(this, args);             } catch (Throwable var5) {                 throw ExceptionUtil.unwrapThrowable(var5);             }         } else {         //判断private final Map<Method, MapperMethod> methodCache;这个map里面有没有这个方法的一级缓存,如果没             MapperMethod mapperMethod = this.cachedMapperMethod(method);             return mapperMethod.execute(this.sqlSession, args);         }     }     //查询一级缓存和设置一级缓存       private MapperMethod cachedMapperMethod(Method method) {         MapperMethod mapperMethod = (MapperMethod)this.methodCache.get(method);         if(mapperMethod == null) {             mapperMethod = new MapperMethod(this.mapperInterface, method, this.sqlSession.getConfiguration());             this.methodCache.put(method, mapperMethod);         }          return mapperMethod;     }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    经过上面的调用后进入MapperMethod里面执行

    //判断sql命令类型 public Object execute(SqlSession sqlSession, Object[] args) {         Object param;         Object result;         if(SqlCommandType.INSERT == this.command.getType()) {             param = this.method.convertArgsToSqlCommandParam(args);             result = this.rowCountResult(sqlSession.insert(this.command.getName(), param));         } else if(SqlCommandType.UPDATE == this.command.getType()) {             param = this.method.convertArgsToSqlCommandParam(args);             result = this.rowCountResult(sqlSession.update(this.command.getName(), param));         } else if(SqlCommandType.DELETE == this.command.getType()) {             param = this.method.convertArgsToSqlCommandParam(args);             result = this.rowCountResult(sqlSession.delete(this.command.getName(), param));         } else if(SqlCommandType.SELECT == this.command.getType()) {         //我们测试的是select类型,则再判断这个方法的返回类型             if(this.method.returnsVoid() && this.method.hasResultHandler()) {                 this.executeWithResultHandler(sqlSession, args);                 result = null;             } else if(this.method.returnsMany()) {                //我们是查询列表,此方法执行                 result = this.executeForMany(sqlSession, args);             } else if(this.method.returnsMap()) {                 result = this.executeForMap(sqlSession, args);             } else {                 param = this.method.convertArgsToSqlCommandParam(args);                 result = sqlSession.selectOne(this.command.getName(), param);             }         } else {             if(SqlCommandType.FLUSH != this.command.getType()) {                 throw new BindingException("Unknown execution method for: " + this.command.getName());             }              result = sqlSession.flushStatements();         }          if(result == null && this.method.getReturnType().isPrimitive() && !this.method.returnsVoid()) {             throw new BindingException("Mapper method '" + this.command.getName() + " attempted to return null from a method with a primitive return type (" + this.method.getReturnType() + ").");         } else {             return result;         }     }  private <E> Object executeForMany(SqlSession sqlSession, Object[] args) { //将param做处理 自动处理为param1,param2..         Object param = this.method.convertArgsToSqlCommandParam(args);         List result;         if(this.method.hasRowBounds()) {             RowBounds rowBounds = this.method.extractRowBounds(args);             //调用该对象的DefaultSqlSession的selectList方法             result = sqlSession.selectList(this.command.getName(), param, rowBounds);         } else {             result = sqlSession.selectList(this.command.getName(), param);         }          return !this.method.getReturnType().isAssignableFrom(result.getClass())?(this.method.getReturnType().isArray()?this.convertToArray(result):this.convertToDeclaredCollection(sqlSession.getConfiguration(), result)):result;     }  //处理参数方法  public Object convertArgsToSqlCommandParam(Object[] args) {             int paramCount = this.params.size();             if(args != null && paramCount != 0) {                 if(!this.hasNamedParameters && paramCount == 1) {                     return args[((Integer)this.params.keySet().iterator().next()).intValue()];                 } else {                     Map<String, Object> param = new MapperMethod.ParamMap();                     int i = 0;                      for(Iterator i$ = this.params.entrySet().iterator(); i$.hasNext(); ++i) {                         Entry<Integer, String> entry = (Entry)i$.next();                         param.put(entry.getValue(), args[((Integer)entry.getKey()).intValue()]);                         String genericParamName = "param" + String.valueOf(i + 1);                         if(!param.containsKey(genericParamName)) {                             param.put(genericParamName, args[((Integer)entry.getKey()).intValue()]);                         }                     }                      return param;                 }             } else {                 return null;             }         } 
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83

    调用DefaultSqlSession的selectList的方法

       public <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds) {         List var5;         try {         //获取MappedStatement对象             MappedStatement ms = this.configuration.getMappedStatement(statement);             //调用cachingExecutor执行器的方法             var5 = this.executor.query(ms, this.wrapCollection(parameter), rowBounds, Executor.NO_RESULT_HANDLER);         } catch (Exception var9) {             throw ExceptionFactory.wrapException("Error querying database.  Cause: " + var9, var9);         } finally {             ErrorContext.instance().reset();         }          return var5;     }  //CachingExector的query方法 public <E> List<E> query(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler) throws SQLException {     //         BoundSql boundSql = ms.getBoundSql(parameterObject);         CacheKey key = this.createCacheKey(ms, parameterObject, rowBounds, boundSql);         //调用下2代码         return this.query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);     }     //2代码  public <E> List<E> query(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException {         Cache cache = ms.getCache();         if(cache != null) {             this.flushCacheIfRequired(ms);             if(ms.isUseCache() && resultHandler == null) {                 this.ensureNoOutParams(ms, parameterObject, boundSql);                 List<E> list = (List)this.tcm.getObject(cache, key);                 if(list == null) {                 //这里是调用Executor里的query方法 如果开启了缓存这掉CachingExecutor的 如果没有则是调用BaseExecutor的                     list = this.delegate.query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);                     this.tcm.putObject(cache, key, list);                 }                  return list;             }         }          return this.delegate.query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);     }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    BaseExecutor的query方法

    public <E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException {         ErrorContext.instance().resource(ms.getResource()).activity("executing a query").object(ms.getId());         if(this.closed) {             throw new ExecutorException("Executor was closed.");         } else {             if(this.queryStack == 0 && ms.isFlushCacheRequired()) {                 this.clearLocalCache();             }              List list;             try {                 ++this.queryStack;                 list = resultHandler == null?(List)this.localCache.getObject(key):null;                 if(list != null) {                     this.handleLocallyCachedOutputParameters(ms, key, parameter, boundSql);                 } else {                 //如果缓存中没有就从数据库中查询                     list = this.queryFromDatabase(ms, parameter, rowBounds, resultHandler, key, boundSql);                 }             } finally {                 --this.queryStack;             }              if(this.queryStack == 0) {                 Iterator i$ = this.deferredLoads.iterator();                  while(i$.hasNext()) {                     BaseExecutor.DeferredLoad deferredLoad = (BaseExecutor.DeferredLoad)i$.next();                     deferredLoad.load();                 }                  this.deferredLoads.clear();                 if(this.configuration.getLocalCacheScope() == LocalCacheScope.STATEMENT) {                     this.clearLocalCache();                 }             }              return list;         }     }  //从数据库中查询 private <E> List<E> queryFromDatabase(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException {         //放入缓存         this.localCache.putObject(key, ExecutionPlaceholder.EXECUTION_PLACEHOLDER);          List list;         try {         //此处是调用子Executor的方法,ExecutorType默认是使用的SimpleExecutor             list = this.doQuery(ms, parameter, rowBounds, resultHandler, boundSql);         } finally {             this.localCache.removeObject(key);         }          this.localCache.putObject(key, list);         if(ms.getStatementType() == StatementType.CALLABLE) {             this.localOutputParameterCache.putObject(key, parameter);         }          return list;     }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61

    SimpleExecutor的doQuery方法

    public <E> List<E> doQuery(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {         Statement stmt = null;          List var9;         try {             Configuration configuration = ms.getConfiguration();             //创建StateMentHandler处理器             StatementHandler handler = configuration.newStatementHandler(this.wrapper, ms, parameter, rowBounds, resultHandler, boundSql);             //调用下3的方法             stmt = this.prepareStatement(handler, ms.getStatementLog());             //调用no4的方法             var9 = handler.query(stmt, resultHandler);         } finally {             this.closeStatement(stmt);         }          return var9;     }     //下3方法 private Statement prepareStatement(StatementHandler handler, Log statementLog) throws SQLException {         Connection connection = this.getConnection(statementLog);         Statement stmt = handler.prepare(connection);         //SatementHanlder 采用PreparedStatementHandler来实现此方法,而PreparedStatementHandler调用的是父接口ParameterHandler的方法         handler.parameterize(stmt);         return stmt;     }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    ParameterHandler参数处理器的方法

    public interface ParameterHandler {     Object getParameterObject();     //此方法是用DefaultParameterHandler实现的     void setParameters(PreparedStatement var1) throws SQLException; }
    • 1
    • 2
    • 3
    • 4
    • 5

    DefaultParameterHandler默认参数处理器的方法

    public void setParameters(PreparedStatement ps) {         ErrorContext.instance().activity("setting parameters").object(this.mappedStatement.getParameterMap().getId());         List<ParameterMapping> parameterMappings = this.boundSql.getParameterMappings();         if(parameterMappings != null) {             for(int i = 0; i < parameterMappings.size(); ++i) {                 ParameterMapping parameterMapping = (ParameterMapping)parameterMappings.get(i);                 if(parameterMapping.getMode() != ParameterMode.OUT) {                     String propertyName = parameterMapping.getProperty();                     Object value;                     if(this.boundSql.hasAdditionalParameter(propertyName)) {                         value = this.boundSql.getAdditionalParameter(propertyName);                     } else if(this.parameterObject == null) {                         value = null;                     } else if(this.typeHandlerRegistry.hasTypeHandler(this.parameterObject.getClass())) {                         value = this.parameterObject;                     } else {                         MetaObject metaObject = this.configuration.newMetaObject(this.parameterObject);                         value = metaObject.getValue(propertyName);                     }                    //这里用调用 TypeHandler类型映射处理器来映射                     TypeHandler typeHandler = parameterMapping.getTypeHandler();                     JdbcType jdbcType = parameterMapping.getJdbcType();                     if(value == null && jdbcType == null) {                         jdbcType = this.configuration.getJdbcTypeForNull();                     }                      try {                     //类型处理器设置参数映射                                                typeHandler.setParameter(ps, i + 1, value, jdbcType);                     } catch (TypeException var10) {                         throw new TypeException("Could not set parameters for mapping: " + parameterMapping + ". Cause: " + var10, var10);                     } catch (SQLException var11) {                         throw new TypeException("Could not set parameters for mapping: " + parameterMapping + ". Cause: " + var11, var11);                     }                 }             }         }      }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    no4的方法

      public <E> List<E> query(Statement statement, ResultHandler resultHandler) throws SQLException {        //此处调用原生sql的处理器         PreparedStatement ps = (PreparedStatement)statement;         //发出原生sql命令         ps.execute();         //采用ResultHandler结果处理器对结果集封装         return this.resultSetHandler.handleResultSets(ps);     }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    ResultHandler代码

    public interface ResultSetHandler {     //此处调用的是DefaultResultSetHandler的方法     <E> List<E> handleResultSets(Statement var1) throws SQLException;      void handleOutputParameters(CallableStatement var1) throws SQLException; } 
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    DefaultResultSetHandler的方法

    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;         ResultSetWrapper rsw = this.getFirstResultSet(stmt);         List<ResultMap> resultMaps = this.mappedStatement.getResultMaps();         int resultMapCount = resultMaps.size();         this.validateResultMapsCount(rsw, resultMapCount);          while(rsw != null && resultMapCount > resultSetCount) {             ResultMap resultMap = (ResultMap)resultMaps.get(resultSetCount);             this.handleResultSet(rsw, resultMap, multipleResults, (ResultMapping)null);             rsw = this.getNextResultSet(stmt);             this.cleanUpAfterHandlingResultSet();             ++resultSetCount;         }          String[] resultSets = this.mappedStatement.getResulSets();         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);     } //处理结果集  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) {                 DefaultResultHandler defaultResultHandler = new DefaultResultHandler(this.objectFactory);                 this.handleRowValues(rsw, resultMap, defaultResultHandler, this.rowBounds, (ResultMapping)null);                 multipleResults.add(defaultResultHandler.getResultList());             } else {                 this.handleRowValues(rsw, resultMap, this.resultHandler, this.rowBounds, (ResultMapping)null);             }         } finally {             this.closeResultSet(rsw.getResultSet());         }      }  private 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);         }      }     private void handleRowValuesForNestedResultMap(ResultSetWrapper rsw, ResultMap resultMap, ResultHandler<?> resultHandler, RowBounds rowBounds, ResultMapping parentMapping) throws SQLException {         DefaultResultContext<Object> resultContext = new DefaultResultContext();         this.skipRows(rsw.getResultSet(), rowBounds);         Object rowValue = null;          while(this.shouldProcessMoreRows(resultContext, rowBounds) && rsw.getResultSet().next()) {             ResultMap discriminatedResultMap = this.resolveDiscriminatedResultMap(rsw.getResultSet(), 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, rsw.getResultSet());                 }         //获取行的值                 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, rsw.getResultSet());                 }             }         }          if(rowValue != null && this.mappedStatement.isResultOrdered() && this.shouldProcessMoreRows(resultContext, rowBounds)) {             this.storeObject(resultHandler, resultContext, rowValue, parentMapping, rsw.getResultSet());         }      }     String resultMapId = resultMap.getId();         Object resultObject = partialObject;         if(partialObject != null) {             MetaObject metaObject = this.configuration.newMetaObject(partialObject);             this.putAncestor(partialObject, resultMapId, columnPrefix);             this.applyNestedResultMappings(rsw, resultMap, metaObject, columnPrefix, combinedKey, false);             this.ancestorObjects.remove(resultMapId);         } else {             ResultLoaderMap lazyLoader = new ResultLoaderMap();             resultObject = this.createResultObject(rsw, resultMap, lazyLoader, columnPrefix);             if(resultObject != null && !this.typeHandlerRegistry.hasTypeHandler(resultMap.getType())) {                 MetaObject metaObject = this.configuration.newMetaObject(resultObject);                 boolean foundValues = !resultMap.getConstructorResultMappings().isEmpty();                 if(this.shouldApplyAutomaticMappings(resultMap, true)) {                     foundValues = this.applyAutomaticMappings(rsw, resultMap, metaObject, columnPrefix) || foundValues;                 }                  foundValues = this.applyPropertyMappings(rsw, resultMap, metaObject, lazyLoader, columnPrefix) || foundValues;                 this.putAncestor(resultObject, resultMapId, columnPrefix);                 foundValues = this.applyNestedResultMappings(rsw, resultMap, metaObject, columnPrefix, combinedKey, true) || foundValues;                 this.ancestorObjects.remove(resultMapId);                 foundValues = lazyLoader.size() > 0 || foundValues;                 resultObject = foundValues?resultObject:null;             }              if(combinedKey != CacheKey.NULL_CACHE_KEY) {                 this.nestedResultObjects.put(combinedKey, resultObject);             }         }          return resultObject;     }   private boolean shouldApplyAutomaticMappings(ResultMap resultMap, boolean isNested) {         return resultMap.getAutoMapping() != null?resultMap.getAutoMapping().booleanValue():(isNested?AutoMappingBehavior.FULL == this.configuration.getAutoMappingBehavior():AutoMappingBehavior.NONE != this.configuration.getAutoMappingBehavior());     }  private boolean applyAutomaticMappings(ResultSetWrapper rsw, ResultMap resultMap, MetaObject metaObject, String columnPrefix) throws SQLException {         List<DefaultResultSetHandler.UnMappedColumAutoMapping> autoMapping = this.createAutomaticMappings(rsw, resultMap, metaObject, columnPrefix);         boolean foundValues = false;         if(autoMapping.size() > 0) {             Iterator i$ = autoMapping.iterator();              while(true) {            //这里使用了内部类对参数和结果集进行映射                DefaultResultSetHandler.UnMappedColumAutoMapping mapping;                 Object value;                 do {                     if(!i$.hasNext()) {                         return foundValues;                     }                      mapping = (DefaultResultSetHandler.UnMappedColumAutoMapping)i$.next();                     value = mapping.typeHandler.getResult(rsw.getResultSet(), mapping.column);                 } while(value == null && !this.configuration.isCallSettersOnNulls());                  if(value != null || !mapping.primitive) {                     metaObject.setValue(mapping.property, value);                 }                  foundValues = true;             }         } else {             return foundValues;         }     }  private static class UnMappedColumAutoMapping {         private final String column;         private final String property;         private final TypeHandler<?> typeHandler;         private final boolean primitive;      //此处才类型器对结果进行映射         public UnMappedColumAutoMapping(String column, String property, TypeHandler<?> typeHandler, boolean primitive) {             this.column = column;             this.property = property;             this.typeHandler = typeHandler;             this.primitive = primitive;         }     }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u014297148/article/details/78696096
  • 相关阅读:
    Erlang 督程 启动和结束子进程
    cocos2d-x 3.0 内存管理机制
    c语言基本数据类型
    4星|《剑桥中国经济史:古代到19世纪》:经济学视角看中国古代史
    孟晚舟三种结局;共享单车大败局;失业潮不会来:4星|《财经》2018年第30期
    2018左其盛差评榜,罕见的差书榜
    2018左其盛好书榜,没见过更好的榜单
    罗振宇时间的朋友2018跨年演讲中最重要的35句话
    中国土地制度与房价走势相关9本书
    2星|水木然《世界在变软》:肤浅的朋友圈鸡汤文
  • 原文地址:https://www.cnblogs.com/xmanblue/p/9151114.html
Copyright © 2020-2023  润新知