Coverage Report - org.apache.ibatis.builder.MapperBuilderAssistant
 
Classes in this File Line Coverage Branch Coverage Complexity
MapperBuilderAssistant
96%
202/209
88%
80/90
3.542
 
 1  
 /**
 2  
  *    Copyright 2009-2015 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.builder;
 17  
 
 18  
 import java.util.ArrayList;
 19  
 import java.util.HashMap;
 20  
 import java.util.HashSet;
 21  
 import java.util.Iterator;
 22  
 import java.util.List;
 23  
 import java.util.Map;
 24  
 import java.util.Properties;
 25  
 import java.util.Set;
 26  
 import java.util.StringTokenizer;
 27  
 
 28  
 import org.apache.ibatis.cache.Cache;
 29  
 import org.apache.ibatis.cache.decorators.LruCache;
 30  
 import org.apache.ibatis.cache.impl.PerpetualCache;
 31  
 import org.apache.ibatis.executor.ErrorContext;
 32  
 import org.apache.ibatis.executor.keygen.KeyGenerator;
 33  
 import org.apache.ibatis.mapping.CacheBuilder;
 34  
 import org.apache.ibatis.mapping.Discriminator;
 35  
 import org.apache.ibatis.mapping.MappedStatement;
 36  
 import org.apache.ibatis.mapping.ParameterMap;
 37  
 import org.apache.ibatis.mapping.ParameterMapping;
 38  
 import org.apache.ibatis.mapping.ParameterMode;
 39  
 import org.apache.ibatis.mapping.ResultFlag;
 40  
 import org.apache.ibatis.mapping.ResultMap;
 41  
 import org.apache.ibatis.mapping.ResultMapping;
 42  
 import org.apache.ibatis.mapping.ResultSetType;
 43  
 import org.apache.ibatis.mapping.SqlCommandType;
 44  
 import org.apache.ibatis.mapping.SqlSource;
 45  
 import org.apache.ibatis.mapping.StatementType;
 46  
 import org.apache.ibatis.reflection.MetaClass;
 47  
 import org.apache.ibatis.scripting.LanguageDriver;
 48  
 import org.apache.ibatis.session.Configuration;
 49  
 import org.apache.ibatis.type.JdbcType;
 50  
 import org.apache.ibatis.type.TypeHandler;
 51  
 
 52  
 /**
 53  
  * @author Clinton Begin
 54  
  */
 55  
 public class MapperBuilderAssistant extends BaseBuilder {
 56  
 
 57  
   private String currentNamespace;
 58  
   private String resource;
 59  
   private Cache currentCache;
 60  
   private boolean unresolvedCacheRef; // issue #676
 61  
 
 62  
   public MapperBuilderAssistant(Configuration configuration, String resource) {
 63  2001
     super(configuration);
 64  2001
     ErrorContext.instance().resource(resource);
 65  2001
     this.resource = resource;
 66  2001
   }
 67  
 
 68  
   public String getCurrentNamespace() {
 69  1215
     return currentNamespace;
 70  
   }
 71  
 
 72  
   public void setCurrentNamespace(String currentNamespace) {
 73  2241
     if (currentNamespace == null) {
 74  0
       throw new BuilderException("The mapper element requires a namespace attribute to be specified.");
 75  
     }
 76  
 
 77  2241
     if (this.currentNamespace != null && !this.currentNamespace.equals(currentNamespace)) {
 78  3
       throw new BuilderException("Wrong namespace. Expected '"
 79  
           + this.currentNamespace + "' but found '" + currentNamespace + "'.");
 80  
     }
 81  
 
 82  2238
     this.currentNamespace = currentNamespace;
 83  2238
   }
 84  
 
 85  
   public String applyCurrentNamespace(String base, boolean isReference) {
 86  62532
     if (base == null) {
 87  32613
       return null;
 88  
     }
 89  29919
     if (isReference) {
 90  
       // is it qualified with any namespace yet?
 91  11256
       if (base.contains(".")) {
 92  1932
         return base;
 93  
       }
 94  
     } else {
 95  
       // is it qualified with this namespace yet?
 96  18663
       if (base.startsWith(currentNamespace + ".")) {
 97  1992
         return base;
 98  
       }
 99  16671
       if (base.contains(".")) {
 100  3
         throw new BuilderException("Dots are not allowed in element names, please remove it from " + base);
 101  
       }
 102  
     }
 103  25992
     return currentNamespace + "." + base;
 104  
   }
 105  
 
 106  
   public Cache useCacheRef(String namespace) {
 107  108
     if (namespace == null) {
 108  0
       throw new BuilderException("cache-ref element requires a namespace attribute.");
 109  
     }
 110  
     try {
 111  108
       unresolvedCacheRef = true;
 112  108
       Cache cache = configuration.getCache(namespace);
 113  36
       if (cache == null) {
 114  0
         throw new IncompleteElementException("No cache for namespace '" + namespace + "' could be found.");
 115  
       }
 116  36
       currentCache = cache;
 117  36
       unresolvedCacheRef = false;
 118  36
       return cache;
 119  72
     } catch (IllegalArgumentException e) {
 120  72
       throw new IncompleteElementException("No cache for namespace '" + namespace + "' could be found.", e);
 121  
     }
 122  
   }
 123  
 
 124  
   public Cache useNewCache(Class<? extends Cache> typeClass,
 125  
       Class<? extends Cache> evictionClass,
 126  
       Long flushInterval,
 127  
       Integer size,
 128  
       boolean readWrite,
 129  
       boolean blocking,
 130  
       Properties props) {
 131  150
     typeClass = valueOrDefault(typeClass, PerpetualCache.class);
 132  150
     evictionClass = valueOrDefault(evictionClass, LruCache.class);
 133  150
     Cache cache = new CacheBuilder(currentNamespace)
 134  
         .implementation(typeClass)
 135  
         .addDecorator(evictionClass)
 136  
         .clearInterval(flushInterval)
 137  
         .size(size)
 138  
         .readWrite(readWrite)
 139  
         .blocking(blocking)
 140  
         .properties(props)
 141  
         .build();
 142  150
     configuration.addCache(cache);
 143  150
     currentCache = cache;
 144  150
     return cache;
 145  
   }
 146  
 
 147  
   public ParameterMap addParameterMap(String id, Class<?> parameterClass, List<ParameterMapping> parameterMappings) {
 148  84
     id = applyCurrentNamespace(id, false);
 149  84
     ParameterMap.Builder parameterMapBuilder = new ParameterMap.Builder(configuration, id, parameterClass, parameterMappings);
 150  84
     ParameterMap parameterMap = parameterMapBuilder.build();
 151  84
     configuration.addParameterMap(parameterMap);
 152  84
     return parameterMap;
 153  
   }
 154  
 
 155  
   public ParameterMapping buildParameterMapping(
 156  
       Class<?> parameterType,
 157  
       String property,
 158  
       Class<?> javaType,
 159  
       JdbcType jdbcType,
 160  
       String resultMap,
 161  
       ParameterMode parameterMode,
 162  
       Class<? extends TypeHandler<?>> typeHandler,
 163  
       Integer numericScale) {
 164  90
     resultMap = applyCurrentNamespace(resultMap, true);
 165  
 
 166  
     // Class parameterType = parameterMapBuilder.type();
 167  90
     Class<?> javaTypeClass = resolveParameterJavaType(parameterType, property, javaType, jdbcType);
 168  90
     TypeHandler<?> typeHandlerInstance = resolveTypeHandler(javaTypeClass, typeHandler);
 169  
 
 170  90
     ParameterMapping.Builder builder = new ParameterMapping.Builder(configuration, property, javaTypeClass);
 171  90
     builder.jdbcType(jdbcType);
 172  90
     builder.resultMapId(resultMap);
 173  90
     builder.mode(parameterMode);
 174  90
     builder.numericScale(numericScale);
 175  90
     builder.typeHandler(typeHandlerInstance);
 176  90
     return builder.build();
 177  
   }
 178  
 
 179  
   public ResultMap addResultMap(
 180  
       String id,
 181  
       Class<?> type,
 182  
       String extend,
 183  
       Discriminator discriminator,
 184  
       List<ResultMapping> resultMappings,
 185  
       Boolean autoMapping) {
 186  5070
     id = applyCurrentNamespace(id, false);
 187  5070
     extend = applyCurrentNamespace(extend, true);
 188  
 
 189  5070
     ResultMap.Builder resultMapBuilder = new ResultMap.Builder(configuration, id, type, resultMappings, autoMapping);
 190  5070
     if (extend != null) {
 191  198
       if (!configuration.hasResultMap(extend)) {
 192  12
         throw new IncompleteElementException("Could not find a parent resultmap with id '" + extend + "'");
 193  
       }
 194  186
       ResultMap resultMap = configuration.getResultMap(extend);
 195  186
       List<ResultMapping> extendedResultMappings = new ArrayList<ResultMapping>(resultMap.getResultMappings());
 196  186
       extendedResultMappings.removeAll(resultMappings);
 197  
       // Remove parent constructor if this resultMap declares a constructor.
 198  186
       boolean declaresConstructor = false;
 199  186
       for (ResultMapping resultMapping : resultMappings) {
 200  108
         if (resultMapping.getFlags().contains(ResultFlag.CONSTRUCTOR)) {
 201  9
           declaresConstructor = true;
 202  9
           break;
 203  
         }
 204  99
       }
 205  186
       if (declaresConstructor) {
 206  9
         Iterator<ResultMapping> extendedResultMappingsIter = extendedResultMappings.iterator();
 207  36
         while (extendedResultMappingsIter.hasNext()) {
 208  27
           if (extendedResultMappingsIter.next().getFlags().contains(ResultFlag.CONSTRUCTOR)) {
 209  18
             extendedResultMappingsIter.remove();
 210  
           }
 211  
         }
 212  
       }
 213  186
       resultMappings.addAll(extendedResultMappings);
 214  
     }
 215  5058
     resultMapBuilder.discriminator(discriminator);
 216  5058
     ResultMap resultMap = resultMapBuilder.build();
 217  5058
     configuration.addResultMap(resultMap);
 218  5058
     return resultMap;
 219  
   }
 220  
 
 221  
   public Discriminator buildDiscriminator(
 222  
       Class<?> resultType,
 223  
       String column,
 224  
       Class<?> javaType,
 225  
       JdbcType jdbcType,
 226  
       Class<? extends TypeHandler<?>> typeHandler,
 227  
       Map<String, String> discriminatorMap) {
 228  333
     ResultMapping resultMapping = buildResultMapping(
 229  
         resultType,
 230  
         null,
 231  
         column,
 232  
         javaType,
 233  
         jdbcType,
 234  
         null,
 235  
         null,
 236  
         null,
 237  
         null,
 238  
         typeHandler,
 239  
         new ArrayList<ResultFlag>(),
 240  
         null,
 241  
         null,
 242  
         false);
 243  333
     Map<String, String> namespaceDiscriminatorMap = new HashMap<String, String>();
 244  333
     for (Map.Entry<String, String> e : discriminatorMap.entrySet()) {
 245  333
       String resultMap = e.getValue();
 246  333
       resultMap = applyCurrentNamespace(resultMap, true);
 247  333
       namespaceDiscriminatorMap.put(e.getKey(), resultMap);
 248  333
     }
 249  333
     Discriminator.Builder discriminatorBuilder = new Discriminator.Builder(configuration, resultMapping, namespaceDiscriminatorMap);
 250  333
     return discriminatorBuilder.build();
 251  
   }
 252  
 
 253  
   public MappedStatement addMappedStatement(
 254  
       String id,
 255  
       SqlSource sqlSource,
 256  
       StatementType statementType,
 257  
       SqlCommandType sqlCommandType,
 258  
       Integer fetchSize,
 259  
       Integer timeout,
 260  
       String parameterMap,
 261  
       Class<?> parameterType,
 262  
       String resultMap,
 263  
       Class<?> resultType,
 264  
       ResultSetType resultSetType,
 265  
       boolean flushCache,
 266  
       boolean useCache,
 267  
       boolean resultOrdered,
 268  
       KeyGenerator keyGenerator,
 269  
       String keyProperty,
 270  
       String keyColumn,
 271  
       String databaseId,
 272  
       LanguageDriver lang,
 273  
       String resultSets) {
 274  
 
 275  6660
     if (unresolvedCacheRef) {
 276  6
       throw new IncompleteElementException("Cache-ref not yet resolved");
 277  
     }
 278  
 
 279  6654
     id = applyCurrentNamespace(id, false);
 280  6654
     boolean isSelect = sqlCommandType == SqlCommandType.SELECT;
 281  
 
 282  6654
     MappedStatement.Builder statementBuilder = new MappedStatement.Builder(configuration, id, sqlSource, sqlCommandType);
 283  6654
     statementBuilder.resource(resource);
 284  6654
     statementBuilder.fetchSize(fetchSize);
 285  6654
     statementBuilder.statementType(statementType);
 286  6654
     statementBuilder.keyGenerator(keyGenerator);
 287  6654
     statementBuilder.keyProperty(keyProperty);
 288  6654
     statementBuilder.keyColumn(keyColumn);
 289  6654
     statementBuilder.databaseId(databaseId);
 290  6654
     statementBuilder.lang(lang);
 291  6654
     statementBuilder.resultOrdered(resultOrdered);
 292  6654
     statementBuilder.resulSets(resultSets);
 293  6654
     setStatementTimeout(timeout, statementBuilder);
 294  
 
 295  6654
     setStatementParameterMap(parameterMap, parameterType, statementBuilder);
 296  6642
     setStatementResultMap(resultMap, resultType, resultSetType, statementBuilder);
 297  6618
     setStatementCache(isSelect, flushCache, useCache, currentCache, statementBuilder);
 298  
 
 299  6618
     MappedStatement statement = statementBuilder.build();
 300  6618
     configuration.addMappedStatement(statement);
 301  6615
     return statement;
 302  
   }
 303  
 
 304  
   private <T> T valueOrDefault(T value, T defaultValue) {
 305  13536
     return value == null ? defaultValue : value;
 306  
   }
 307  
 
 308  
   private void setStatementCache(
 309  
       boolean isSelect,
 310  
       boolean flushCache,
 311  
       boolean useCache,
 312  
       Cache cache,
 313  
       MappedStatement.Builder statementBuilder) {
 314  6618
     flushCache = valueOrDefault(flushCache, !isSelect);
 315  6618
     useCache = valueOrDefault(useCache, isSelect);
 316  6618
     statementBuilder.flushCacheRequired(flushCache);
 317  6618
     statementBuilder.useCache(useCache);
 318  6618
     statementBuilder.cache(cache);
 319  6618
   }
 320  
 
 321  
   private void setStatementParameterMap(
 322  
       String parameterMap,
 323  
       Class<?> parameterTypeClass,
 324  
       MappedStatement.Builder statementBuilder) {
 325  6654
     parameterMap = applyCurrentNamespace(parameterMap, true);
 326  
 
 327  6654
     if (parameterMap != null) {
 328  
       try {
 329  171
         statementBuilder.parameterMap(configuration.getParameterMap(parameterMap));
 330  12
       } catch (IllegalArgumentException e) {
 331  12
         throw new IncompleteElementException("Could not find parameter map " + parameterMap, e);
 332  159
       }
 333  6483
     } else if (parameterTypeClass != null) {
 334  3369
       List<ParameterMapping> parameterMappings = new ArrayList<ParameterMapping>();
 335  3369
       ParameterMap.Builder inlineParameterMapBuilder = new ParameterMap.Builder(
 336  
           configuration,
 337  
           statementBuilder.id() + "-Inline",
 338  
           parameterTypeClass,
 339  
           parameterMappings);
 340  3369
       statementBuilder.parameterMap(inlineParameterMapBuilder.build());
 341  
     }
 342  6642
   }
 343  
 
 344  
   private void setStatementResultMap(
 345  
       String resultMap,
 346  
       Class<?> resultType,
 347  
       ResultSetType resultSetType,
 348  
       MappedStatement.Builder statementBuilder) {
 349  6642
     resultMap = applyCurrentNamespace(resultMap, true);
 350  
 
 351  6642
     List<ResultMap> resultMaps = new ArrayList<ResultMap>();
 352  6642
     if (resultMap != null) {
 353  2232
       String[] resultMapNames = resultMap.split(",");
 354  4449
       for (String resultMapName : resultMapNames) {
 355  
         try {
 356  2241
           resultMaps.add(configuration.getResultMap(resultMapName.trim()));
 357  24
         } catch (IllegalArgumentException e) {
 358  24
           throw new IncompleteElementException("Could not find result map " + resultMapName, e);
 359  2217
         }
 360  
       }
 361  2208
     } else if (resultType != null) {
 362  3060
       ResultMap.Builder inlineResultMapBuilder = new ResultMap.Builder(
 363  
           configuration,
 364  
           statementBuilder.id() + "-Inline",
 365  
           resultType,
 366  
           new ArrayList<ResultMapping>(),
 367  
           null);
 368  3060
       resultMaps.add(inlineResultMapBuilder.build());
 369  
     }
 370  6618
     statementBuilder.resultMaps(resultMaps);
 371  
 
 372  6618
     statementBuilder.resultSetType(resultSetType);
 373  6618
   }
 374  
 
 375  
   private void setStatementTimeout(Integer timeout, MappedStatement.Builder statementBuilder) {
 376  6654
     if (timeout == null) {
 377  6654
       timeout = configuration.getDefaultStatementTimeout();
 378  
     }
 379  6654
     statementBuilder.timeout(timeout);
 380  6654
   }
 381  
 
 382  
   public ResultMapping buildResultMapping(
 383  
       Class<?> resultType,
 384  
       String property,
 385  
       String column,
 386  
       Class<?> javaType,
 387  
       JdbcType jdbcType,
 388  
       String nestedSelect,
 389  
       String nestedResultMap,
 390  
       String notNullColumn,
 391  
       String columnPrefix,
 392  
       Class<? extends TypeHandler<?>> typeHandler,
 393  
       List<ResultFlag> flags,
 394  
       String resultSet,
 395  
       String foreignColumn,
 396  
       boolean lazy) {
 397  9804
     Class<?> javaTypeClass = resolveResultJavaType(resultType, property, javaType);
 398  9804
     TypeHandler<?> typeHandlerInstance = resolveTypeHandler(javaTypeClass, typeHandler);
 399  9804
     List<ResultMapping> composites = parseCompositeColumnName(column);
 400  9804
     if (composites.size() > 0) {
 401  90
       column = null;
 402  
     }
 403  9804
     ResultMapping.Builder builder = new ResultMapping.Builder(configuration, property, column, javaTypeClass);
 404  9804
     builder.jdbcType(jdbcType);
 405  9804
     builder.nestedQueryId(applyCurrentNamespace(nestedSelect, true));
 406  9804
     builder.nestedResultMapId(applyCurrentNamespace(nestedResultMap, true));
 407  9804
     builder.resultSet(resultSet);
 408  9804
     builder.typeHandler(typeHandlerInstance);
 409  9804
     builder.flags(flags == null ? new ArrayList<ResultFlag>() : flags);
 410  9804
     builder.composites(composites);
 411  9804
     builder.notNullColumns(parseMultipleColumnNames(notNullColumn));
 412  9804
     builder.columnPrefix(columnPrefix);
 413  9804
     builder.foreignColumn(foreignColumn);
 414  9804
     builder.lazy(lazy);
 415  9804
     return builder.build();
 416  
   }
 417  
 
 418  
   private Set<String> parseMultipleColumnNames(String columnName) {
 419  9804
     Set<String> columns = new HashSet<String>();
 420  9804
     if (columnName != null) {
 421  60
       if (columnName.indexOf(',') > -1) {
 422  6
         StringTokenizer parser = new StringTokenizer(columnName, "{}, ", false);
 423  18
         while (parser.hasMoreTokens()) {
 424  12
           String column = parser.nextToken();
 425  12
           columns.add(column);
 426  12
         }
 427  6
       } else {
 428  54
         columns.add(columnName);
 429  
       }
 430  
     }
 431  9804
     return columns;
 432  
   }
 433  
 
 434  
   private List<ResultMapping> parseCompositeColumnName(String columnName) {
 435  9804
     List<ResultMapping> composites = new ArrayList<ResultMapping>();
 436  9804
     if (columnName != null && (columnName.indexOf('=') > -1 || columnName.indexOf(',') > -1)) {
 437  90
       StringTokenizer parser = new StringTokenizer(columnName, "{}=, ", false);
 438  192
       while (parser.hasMoreTokens()) {
 439  102
         String property = parser.nextToken();
 440  102
         String column = parser.nextToken();
 441  102
         ResultMapping.Builder complexBuilder = new ResultMapping.Builder(configuration, property, column, configuration.getTypeHandlerRegistry().getUnknownTypeHandler());
 442  102
         composites.add(complexBuilder.build());
 443  102
       }
 444  
     }
 445  9804
     return composites;
 446  
   }
 447  
 
 448  
   private Class<?> resolveResultJavaType(Class<?> resultType, String property, Class<?> javaType) {
 449  9804
     if (javaType == null && property != null) {
 450  
       try {
 451  7323
         MetaClass metaResultType = MetaClass.forClass(resultType, configuration.getReflectorFactory());
 452  6891
         javaType = metaResultType.getSetterType(property);
 453  447
       } catch (Exception e) {
 454  
         //ignore, following null check statement will deal with the situation
 455  6876
       }
 456  
     }
 457  9804
     if (javaType == null) {
 458  477
       javaType = Object.class;
 459  
     }
 460  9804
     return javaType;
 461  
   }
 462  
 
 463  
   private Class<?> resolveParameterJavaType(Class<?> resultType, String property, Class<?> javaType, JdbcType jdbcType) {
 464  90
     if (javaType == null) {
 465  90
       if (JdbcType.CURSOR.equals(jdbcType)) {
 466  0
         javaType = java.sql.ResultSet.class;
 467  90
       } else if (Map.class.isAssignableFrom(resultType)) {
 468  9
         javaType = Object.class;
 469  
       } else {
 470  81
         MetaClass metaResultType = MetaClass.forClass(resultType, configuration.getReflectorFactory());
 471  81
         javaType = metaResultType.getGetterType(property);
 472  
       }
 473  
     }
 474  90
     if (javaType == null) {
 475  0
       javaType = Object.class;
 476  
     }
 477  90
     return javaType;
 478  
   }
 479  
 
 480  
   /** Backward compatibility signature */
 481  
   public ResultMapping buildResultMapping(
 482  
       Class<?> resultType,
 483  
       String property,
 484  
       String column,
 485  
       Class<?> javaType,
 486  
       JdbcType jdbcType,
 487  
       String nestedSelect,
 488  
       String nestedResultMap,
 489  
       String notNullColumn,
 490  
       String columnPrefix,
 491  
       Class<? extends TypeHandler<?>> typeHandler,
 492  
       List<ResultFlag> flags) {
 493  0
       return buildResultMapping(
 494  
         resultType, property, column, javaType, jdbcType, nestedSelect,
 495  
         nestedResultMap, notNullColumn, columnPrefix, typeHandler, flags, null, null, configuration.isLazyLoadingEnabled());
 496  
   }
 497  
 
 498  
   public LanguageDriver getLanguageDriver(Class<?> langClass) {
 499  8553
     if (langClass != null) {
 500  21
       configuration.getLanguageRegistry().register(langClass);
 501  
     } else {
 502  8532
       langClass = configuration.getLanguageRegistry().getDefaultDriverClass();
 503  
     }
 504  8553
     return configuration.getLanguageRegistry().getDriver(langClass);
 505  
   }
 506  
 
 507  
   /** Backward compatibility signature */
 508  
   public MappedStatement addMappedStatement(
 509  
     String id,
 510  
     SqlSource sqlSource,
 511  
     StatementType statementType,
 512  
     SqlCommandType sqlCommandType,
 513  
     Integer fetchSize,
 514  
     Integer timeout,
 515  
     String parameterMap,
 516  
     Class<?> parameterType,
 517  
     String resultMap,
 518  
     Class<?> resultType,
 519  
     ResultSetType resultSetType,
 520  
     boolean flushCache,
 521  
     boolean useCache,
 522  
     boolean resultOrdered,
 523  
     KeyGenerator keyGenerator,
 524  
     String keyProperty,
 525  
     String keyColumn,
 526  
     String databaseId,
 527  
     LanguageDriver lang) {
 528  0
     return addMappedStatement(
 529  
       id, sqlSource, statementType, sqlCommandType, fetchSize, timeout,
 530  
       parameterMap, parameterType, resultMap, resultType, resultSetType,
 531  
       flushCache, useCache, resultOrdered, keyGenerator, keyProperty,
 532  
       keyColumn, databaseId, lang, null);
 533  
   }
 534  
 
 535  
 }