View Javadoc
1   /*
2    *    Copyright 2009-2021 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    *       http://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  
18  import java.sql.SQLException;
19  import java.util.List;
20  
21  import javax.sql.DataSource;
22  
23  import org.apache.ibatis.cache.CacheKey;
24  import org.apache.ibatis.executor.Executor;
25  import org.apache.ibatis.executor.ExecutorException;
26  import org.apache.ibatis.executor.ResultExtractor;
27  import org.apache.ibatis.mapping.BoundSql;
28  import org.apache.ibatis.mapping.Environment;
29  import org.apache.ibatis.mapping.MappedStatement;
30  import org.apache.ibatis.reflection.factory.ObjectFactory;
31  import org.apache.ibatis.session.Configuration;
32  import org.apache.ibatis.session.ExecutorType;
33  import org.apache.ibatis.session.RowBounds;
34  import org.apache.ibatis.transaction.Transaction;
35  import org.apache.ibatis.transaction.TransactionFactory;
36  
37  /**
38   * @author Clinton Begin
39   */
40  public class ResultLoader {
41  
42    protected final Configuration configuration;
43    protected final Executor executor;
44    protected final MappedStatement mappedStatement;
45    protected final Object parameterObject;
46    protected final Class<?> targetType;
47    protected final ObjectFactory objectFactory;
48    protected final CacheKey cacheKey;
49    protected final BoundSql boundSql;
50    protected final ResultExtractor resultExtractor;
51    protected final long creatorThreadId;
52  
53    protected boolean loaded;
54    protected Object resultObject;
55  
56    public ResultLoader(Configuration config, Executor executor, MappedStatement mappedStatement, Object parameterObject, Class<?> targetType, CacheKey cacheKey, BoundSql boundSql) {
57      this.configuration = config;
58      this.executor = executor;
59      this.mappedStatement = mappedStatement;
60      this.parameterObject = parameterObject;
61      this.targetType = targetType;
62      this.objectFactory = configuration.getObjectFactory();
63      this.cacheKey = cacheKey;
64      this.boundSql = boundSql;
65      this.resultExtractor = new ResultExtractor(configuration, objectFactory);
66      this.creatorThreadId = Thread.currentThread().getId();
67    }
68  
69    public Object loadResult() throws SQLException {
70      List<Object> list = selectList();
71      resultObject = resultExtractor.extractObjectFromList(list, targetType);
72      return resultObject;
73    }
74  
75    private <E> List<E> selectList() throws SQLException {
76      Executor localExecutor = executor;
77      if (Thread.currentThread().getId() != this.creatorThreadId || localExecutor.isClosed()) {
78        localExecutor = newExecutor();
79      }
80      try {
81        return localExecutor.query(mappedStatement, parameterObject, RowBounds.DEFAULT, Executor.NO_RESULT_HANDLER, cacheKey, boundSql);
82      } finally {
83        if (localExecutor != executor) {
84          localExecutor.close(false);
85        }
86      }
87    }
88  
89    private Executor newExecutor() {
90      final Environment environment = configuration.getEnvironment();
91      if (environment == null) {
92        throw new ExecutorException("ResultLoader could not load lazily.  Environment was not configured.");
93      }
94      final DataSource ds = environment.getDataSource();
95      if (ds == null) {
96        throw new ExecutorException("ResultLoader could not load lazily.  DataSource was not configured.");
97      }
98      final TransactionFactory transactionFactory = environment.getTransactionFactory();
99      final Transaction tx = transactionFactory.newTransaction(ds, null, false);
100     return configuration.newExecutor(tx, ExecutorType.SIMPLE);
101   }
102 
103   public boolean wasNull() {
104     return resultObject == null;
105   }
106 
107 }