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.mapping;
17  
18  import java.util.ArrayList;
19  import java.util.Collections;
20  import java.util.List;
21  
22  import org.apache.ibatis.cache.Cache;
23  import org.apache.ibatis.executor.keygen.Jdbc3KeyGenerator;
24  import org.apache.ibatis.executor.keygen.KeyGenerator;
25  import org.apache.ibatis.executor.keygen.NoKeyGenerator;
26  import org.apache.ibatis.logging.Log;
27  import org.apache.ibatis.logging.LogFactory;
28  import org.apache.ibatis.scripting.LanguageDriver;
29  import org.apache.ibatis.session.Configuration;
30  
31  /**
32   * @author Clinton Begin
33   */
34  public final class MappedStatement {
35  
36    private String resource;
37    private Configuration configuration;
38    private String id;
39    private Integer fetchSize;
40    private Integer timeout;
41    private StatementType statementType;
42    private ResultSetType resultSetType;
43    private SqlSource sqlSource;
44    private Cache cache;
45    private ParameterMap parameterMap;
46    private List<ResultMap> resultMaps;
47    private boolean flushCacheRequired;
48    private boolean useCache;
49    private boolean resultOrdered;
50    private SqlCommandType sqlCommandType;
51    private KeyGenerator keyGenerator;
52    private String[] keyProperties;
53    private String[] keyColumns;
54    private boolean hasNestedResultMaps;
55    private String databaseId;
56    private Log statementLog;
57    private LanguageDriver lang;
58    private String[] resultSets;
59  
60    MappedStatement() {
61      // constructor disabled
62    }
63  
64    public static class Builder {
65      private MappedStatement mappedStatement = new MappedStatement();
66  
67      public Builder(Configuration configuration, String id, SqlSource sqlSource, SqlCommandType sqlCommandType) {
68        mappedStatement.configuration = configuration;
69        mappedStatement.id = id;
70        mappedStatement.sqlSource = sqlSource;
71        mappedStatement.statementType = StatementType.PREPARED;
72        mappedStatement.resultSetType = ResultSetType.DEFAULT;
73        mappedStatement.parameterMap = new ParameterMap.Builder(configuration, "defaultParameterMap", null, new ArrayList<>()).build();
74        mappedStatement.resultMaps = new ArrayList<>();
75        mappedStatement.sqlCommandType = sqlCommandType;
76        mappedStatement.keyGenerator = configuration.isUseGeneratedKeys() && SqlCommandType.INSERT.equals(sqlCommandType) ? Jdbc3KeyGenerator.INSTANCE : NoKeyGenerator.INSTANCE;
77        String logId = id;
78        if (configuration.getLogPrefix() != null) {
79          logId = configuration.getLogPrefix() + id;
80        }
81        mappedStatement.statementLog = LogFactory.getLog(logId);
82        mappedStatement.lang = configuration.getDefaultScriptingLanguageInstance();
83      }
84  
85      public Builder resource(String resource) {
86        mappedStatement.resource = resource;
87        return this;
88      }
89  
90      public String id() {
91        return mappedStatement.id;
92      }
93  
94      public Builder parameterMap(ParameterMap parameterMap) {
95        mappedStatement.parameterMap = parameterMap;
96        return this;
97      }
98  
99      public Builder resultMaps(List<ResultMap> resultMaps) {
100       mappedStatement.resultMaps = resultMaps;
101       for (ResultMap resultMap : resultMaps) {
102         mappedStatement.hasNestedResultMaps = mappedStatement.hasNestedResultMaps || resultMap.hasNestedResultMaps();
103       }
104       return this;
105     }
106 
107     public Builder fetchSize(Integer fetchSize) {
108       mappedStatement.fetchSize = fetchSize;
109       return this;
110     }
111 
112     public Builder timeout(Integer timeout) {
113       mappedStatement.timeout = timeout;
114       return this;
115     }
116 
117     public Builder statementType(StatementType statementType) {
118       mappedStatement.statementType = statementType;
119       return this;
120     }
121 
122     public Builder resultSetType(ResultSetType resultSetType) {
123       mappedStatement.resultSetType = resultSetType == null ? ResultSetType.DEFAULT : resultSetType;
124       return this;
125     }
126 
127     public Builder cache(Cache cache) {
128       mappedStatement.cache = cache;
129       return this;
130     }
131 
132     public Builder flushCacheRequired(boolean flushCacheRequired) {
133       mappedStatement.flushCacheRequired = flushCacheRequired;
134       return this;
135     }
136 
137     public Builder useCache(boolean useCache) {
138       mappedStatement.useCache = useCache;
139       return this;
140     }
141 
142     public Builder resultOrdered(boolean resultOrdered) {
143       mappedStatement.resultOrdered = resultOrdered;
144       return this;
145     }
146 
147     public Builder keyGenerator(KeyGenerator keyGenerator) {
148       mappedStatement.keyGenerator = keyGenerator;
149       return this;
150     }
151 
152     public Builder keyProperty(String keyProperty) {
153       mappedStatement.keyProperties = delimitedStringToArray(keyProperty);
154       return this;
155     }
156 
157     public Builder keyColumn(String keyColumn) {
158       mappedStatement.keyColumns = delimitedStringToArray(keyColumn);
159       return this;
160     }
161 
162     public Builder databaseId(String databaseId) {
163       mappedStatement.databaseId = databaseId;
164       return this;
165     }
166 
167     public Builder lang(LanguageDriver driver) {
168       mappedStatement.lang = driver;
169       return this;
170     }
171 
172     public Builder resultSets(String resultSet) {
173       mappedStatement.resultSets = delimitedStringToArray(resultSet);
174       return this;
175     }
176 
177     /**
178      * Resul sets.
179      *
180      * @param resultSet
181      *          the result set
182      * @return the builder
183      * @deprecated Use {@link #resultSets}
184      */
185     @Deprecated
186     public Builder resulSets(String resultSet) {
187       mappedStatement.resultSets = delimitedStringToArray(resultSet);
188       return this;
189     }
190 
191     public MappedStatement build() {
192       assert mappedStatement.configuration != null;
193       assert mappedStatement.id != null;
194       assert mappedStatement.sqlSource != null;
195       assert mappedStatement.lang != null;
196       mappedStatement.resultMaps = Collections.unmodifiableList(mappedStatement.resultMaps);
197       return mappedStatement;
198     }
199   }
200 
201   public KeyGenerator getKeyGenerator() {
202     return keyGenerator;
203   }
204 
205   public SqlCommandType getSqlCommandType() {
206     return sqlCommandType;
207   }
208 
209   public String getResource() {
210     return resource;
211   }
212 
213   public Configuration getConfiguration() {
214     return configuration;
215   }
216 
217   public String getId() {
218     return id;
219   }
220 
221   public boolean hasNestedResultMaps() {
222     return hasNestedResultMaps;
223   }
224 
225   public Integer getFetchSize() {
226     return fetchSize;
227   }
228 
229   public Integer getTimeout() {
230     return timeout;
231   }
232 
233   public StatementType getStatementType() {
234     return statementType;
235   }
236 
237   public ResultSetType getResultSetType() {
238     return resultSetType;
239   }
240 
241   public SqlSource getSqlSource() {
242     return sqlSource;
243   }
244 
245   public ParameterMap getParameterMap() {
246     return parameterMap;
247   }
248 
249   public List<ResultMap> getResultMaps() {
250     return resultMaps;
251   }
252 
253   public Cache getCache() {
254     return cache;
255   }
256 
257   public boolean isFlushCacheRequired() {
258     return flushCacheRequired;
259   }
260 
261   public boolean isUseCache() {
262     return useCache;
263   }
264 
265   public boolean isResultOrdered() {
266     return resultOrdered;
267   }
268 
269   public String getDatabaseId() {
270     return databaseId;
271   }
272 
273   public String[] getKeyProperties() {
274     return keyProperties;
275   }
276 
277   public String[] getKeyColumns() {
278     return keyColumns;
279   }
280 
281   public Log getStatementLog() {
282     return statementLog;
283   }
284 
285   public LanguageDriver getLang() {
286     return lang;
287   }
288 
289   public String[] getResultSets() {
290     return resultSets;
291   }
292 
293   /**
294    * Gets the resul sets.
295    *
296    * @return the resul sets
297    * @deprecated Use {@link #getResultSets()}
298    */
299   @Deprecated
300   public String[] getResulSets() {
301     return resultSets;
302   }
303 
304   public BoundSql getBoundSql(Object parameterObject) {
305     BoundSql boundSql = sqlSource.getBoundSql(parameterObject);
306     List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
307     if (parameterMappings == null || parameterMappings.isEmpty()) {
308       boundSql = new BoundSql(configuration, boundSql.getSql(), parameterMap.getParameterMappings(), parameterObject);
309     }
310 
311     // check for nested result maps in parameter mappings (issue #30)
312     for (ParameterMapping pm : boundSql.getParameterMappings()) {
313       String rmId = pm.getResultMapId();
314       if (rmId != null) {
315         ResultMap rm = configuration.getResultMap(rmId);
316         if (rm != null) {
317           hasNestedResultMaps |= rm.hasNestedResultMaps();
318         }
319       }
320     }
321 
322     return boundSql;
323   }
324 
325   private static String[] delimitedStringToArray(String in) {
326     if (in == null || in.trim().length() == 0) {
327       return null;
328     } else {
329       return in.split(",");
330     }
331   }
332 
333 }