ResultLoader.java

  1. /*
  2.  *    Copyright 2009-2024 the original author or authors.
  3.  *
  4.  *    Licensed under the Apache License, Version 2.0 (the "License");
  5.  *    you may not use this file except in compliance with the License.
  6.  *    You may obtain a copy of the License at
  7.  *
  8.  *       https://www.apache.org/licenses/LICENSE-2.0
  9.  *
  10.  *    Unless required by applicable law or agreed to in writing, software
  11.  *    distributed under the License is distributed on an "AS IS" BASIS,
  12.  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13.  *    See the License for the specific language governing permissions and
  14.  *    limitations under the License.
  15.  */
  16. package org.apache.ibatis.executor.loader;

  17. import java.sql.SQLException;
  18. import java.util.List;

  19. import javax.sql.DataSource;

  20. import org.apache.ibatis.cache.CacheKey;
  21. import org.apache.ibatis.executor.Executor;
  22. import org.apache.ibatis.executor.ExecutorException;
  23. import org.apache.ibatis.executor.ResultExtractor;
  24. import org.apache.ibatis.mapping.BoundSql;
  25. import org.apache.ibatis.mapping.Environment;
  26. import org.apache.ibatis.mapping.MappedStatement;
  27. import org.apache.ibatis.reflection.factory.ObjectFactory;
  28. import org.apache.ibatis.session.Configuration;
  29. import org.apache.ibatis.session.ExecutorType;
  30. import org.apache.ibatis.session.RowBounds;
  31. import org.apache.ibatis.transaction.Transaction;
  32. import org.apache.ibatis.transaction.TransactionFactory;

  33. /**
  34.  * @author Clinton Begin
  35.  */
  36. public class ResultLoader {

  37.   protected final Configuration configuration;
  38.   protected final Executor executor;
  39.   protected final MappedStatement mappedStatement;
  40.   protected final Object parameterObject;
  41.   protected final Class<?> targetType;
  42.   protected final ObjectFactory objectFactory;
  43.   protected final CacheKey cacheKey;
  44.   protected final BoundSql boundSql;
  45.   protected final ResultExtractor resultExtractor;
  46.   protected final long creatorThreadId;

  47.   protected boolean loaded;
  48.   protected Object resultObject;

  49.   public ResultLoader(Configuration config, Executor executor, MappedStatement mappedStatement, Object parameterObject,
  50.       Class<?> targetType, CacheKey cacheKey, BoundSql boundSql) {
  51.     this.configuration = config;
  52.     this.executor = executor;
  53.     this.mappedStatement = mappedStatement;
  54.     this.parameterObject = parameterObject;
  55.     this.targetType = targetType;
  56.     this.objectFactory = configuration.getObjectFactory();
  57.     this.cacheKey = cacheKey;
  58.     this.boundSql = boundSql;
  59.     this.resultExtractor = new ResultExtractor(configuration, objectFactory);
  60.     this.creatorThreadId = Thread.currentThread().getId();
  61.   }

  62.   public Object loadResult() throws SQLException {
  63.     List<Object> list = selectList();
  64.     resultObject = resultExtractor.extractObjectFromList(list, targetType);
  65.     return resultObject;
  66.   }

  67.   private <E> List<E> selectList() throws SQLException {
  68.     Executor localExecutor = executor;
  69.     if (Thread.currentThread().getId() != this.creatorThreadId || localExecutor.isClosed()) {
  70.       localExecutor = newExecutor();
  71.     }
  72.     try {
  73.       return localExecutor.query(mappedStatement, parameterObject, RowBounds.DEFAULT, Executor.NO_RESULT_HANDLER,
  74.           cacheKey, boundSql);
  75.     } finally {
  76.       if (localExecutor != executor) {
  77.         localExecutor.close(false);
  78.       }
  79.     }
  80.   }

  81.   private Executor newExecutor() {
  82.     final Environment environment = configuration.getEnvironment();
  83.     if (environment == null) {
  84.       throw new ExecutorException("ResultLoader could not load lazily.  Environment was not configured.");
  85.     }
  86.     final DataSource ds = environment.getDataSource();
  87.     if (ds == null) {
  88.       throw new ExecutorException("ResultLoader could not load lazily.  DataSource was not configured.");
  89.     }
  90.     final TransactionFactory transactionFactory = environment.getTransactionFactory();
  91.     final Transaction tx = transactionFactory.newTransaction(ds, null, false);
  92.     return configuration.newExecutor(tx, ExecutorType.SIMPLE);
  93.   }

  94.   public boolean wasNull() {
  95.     return resultObject == null;
  96.   }

  97. }