Mybatisロード解析Mapper(xml)ファイル第二話


もっと読む
Sql Session Factory初期化:http://donald-draper.iteye.com/admin/blogs/2331917
Mybatisロード解析Mapper(xml)ファイル第一話:http://donald-draper.iteye.com/blog/2333125
Mapper対応のxmlファイルを解析すると、実際には解析xmlのmapper Xnode、具体的にはnamespace属性、cache、cache-ref、parameterMap、reultMap、sql、およびselect insert udateサブノードになります。前の記事では、Manacheceという属性の解析を行います。及びselect insert 124アップデテサブノードの解析
まず次の方法から見ます。
//Mapper xmlファイルを読み込み、解析する
 private void mapperElement(XNode parent)
        throws Exception
    {
        if(parent != null)
        {
            for(Iterator i$ = parent.getChildren().iterator(); i$.hasNext();)
            {
                XNode child = (XNode)i$.next();
                if("package".equals(child.getName()))
                {
                    String mapperPackage = child.getStringAttribute("name");
                    configuration.addMappers(mapperPackage);
                } else
                {
                    String resource = child.getStringAttribute("resource");
                    String url = child.getStringAttribute("url");
                    String mapperClass = child.getStringAttribute("class");
		     //     resource,  Mapper
                    if(resource != null && url == null && mapperClass == null)
                    {
                        ErrorContext.instance().resource(resource);
			//  Mapper resource  
                        InputStream inputStream = Resources.getResourceAsStream(resource);
		          XMLMapperBuilder
                        XMLMapperBuilder mapperParser = new XMLMapperBuilder(inputStream, configuration, resource, configuration.getSqlFragments());
                        mapperParser.parse();
                    } else
                    if(resource == null && url != null && mapperClass == null)
                    {
                        ErrorContext.instance().resource(url);
                        InputStream inputStream = Resources.getUrlAsStream(url);
                        XMLMapperBuilder mapperParser = new XMLMapperBuilder(inputStream, configuration, url, configuration.getSqlFragments());
                        mapperParser.parse();
                    } else
		    //          
		    //     class,  Mapper
                    if(resource == null && url == null && mapperClass != null)
                    {
		       
                        Class mapperInterface = Resources.classForName(mapperClass);
			//mapperInterface     configuration
                        configuration.addMapper(mapperInterface);
                    } else
                    {
                        throw new BuilderException("A mapper element may only specify a url, resource or class, but not more than one.");
                    }
                }
            }

        }
   }
//XMLMapperBuider
public class XMLMapperBuilder extends BaseBuilder
{
    private XPathParser parser;
    private MapperBuilderAssistant builderAssistant;
    private Map sqlFragments;
    private String resource;
    //  XMLMapperBuilder
    public XMLMapperBuilder(InputStream inputStream, Configuration configuration, String resource, Map sqlFragments)
    {
        this(new XPathParser(inputStream, true, configuration.getVariables(), new XMLMapperEntityResolver()), configuration, resource, sqlFragments);
    }

    private XMLMapperBuilder(XPathParser parser, Configuration configuration, String resource, Map sqlFragments)
    {
        super(configuration);
	//  MapperBuilderAssistant
        builderAssistant = new MapperBuilderAssistant(configuration, resource);
        this.parser = parser;
        this.sqlFragments = sqlFragments;
        this.resource = resource;
    }
     public void parse()
    {
        if(!configuration.isResourceLoaded(resource))
        {
	    //  configuration      ,   Mapper xml  ,
	    
            configurationElement(parser.evalNode("/mapper"));
	    //      configuration Set resource
            configuration.addLoadedResource(resource);
	    //  Mapper     
            bindMapperForNamespace();
        }
	// configuration       ResultMaps
        parsePendingResultMaps();
        // configuration       ChacheRefs
        parsePendingChacheRefs();
        // configuration       Statements
        parsePendingStatements();
    }
    //  mapper Xnode   ,namespace,cache,cache-ref,parameterMap,resultMap,
    //sql, select|insert|update|delete   
     private void configurationElement(XNode context)
    {
        try
        {
            String namespace = context.getStringAttribute("namespace");
            builderAssistant.setCurrentNamespace(namespace);
            cacheRefElement(context.evalNode("cache-ref"));
            cacheElement(context.evalNode("cache"));
            parameterMapElement(context.evalNodes("/mapper/parameterMap"));
	    //               ,          
            resultMapElements(context.evalNodes("/mapper/resultMap"));
            sqlElement(context.evalNodes("/mapper/sql"));
            buildStatementFromContext(context.evalNodes("select|insert|update|delete"));
        }
        catch(Exception e)
        {
            throw new RuntimeException((new StringBuilder()).append("Error parsing Mapper XML. Cause: ").append(e).toString(), e);
        }
    }
}
//Configration、Mapper xmlファイル名をSet loaded Resourceに追加します。
//その中でkeyはclassのフルネームで、comp.mapper.UserMapper
  public void addLoadedResource(String resource)
    {
        loadedResources.add(resource);
    }
//resultMapの設定
result MapElements(context.eval Nodes);
//XMLMapperBuider
//エルゴード解析resultMapノード
private void resultMapElements(List list)
        throws Exception
    {
        for(Iterator i$ = list.iterator(); i$.hasNext();)
        {
            XNode resultMapNode = (XNode)i$.next();
            try
            { 
	        //  resultMap  
                resultMapElement(resultMapNode);
            }
            catch(IncompleteElementException e) { }
        }
    }
    //  resultMap  
    private ResultMap resultMapElement(XNode resultMapNode)
        throws Exception
    {
        //   resultMapElement  
        return resultMapElement(resultMapNode, Collections.emptyList());
    }
    //    resultMap  
    private ResultMap resultMapElement(XNode resultMapNode, List additionalResultMappings)
        throws Exception
    {
        ResultMapResolver resultMapResolver;
        ErrorContext.instance().activity((new StringBuilder()).append("processing ").append(resultMapNode.getValueBasedIdentifier()).toString());
        //  resultMap id,type,extends,autoMapping
	String id = resultMapNode.getStringAttribute("id", resultMapNode.getValueBasedIdentifier());
        String type = resultMapNode.getStringAttribute("type", resultMapNode.getStringAttribute("ofType", resultMapNode.getStringAttribute("resultType", resultMapNode.getStringAttribute("javaType"))));
        String extend = resultMapNode.getStringAttribute("extends");
        Boolean autoMapping = resultMapNode.getBooleanAttribute("autoMapping", null);
        Class typeClass = resolveClass(type);
        Discriminator discriminator = null;
        List resultMappings = new ArrayList();
        resultMappings.addAll(additionalResultMappings);
        List resultChildren = resultMapNode.getChildren();
	//resultMap     result   ,  result    ,  ResultMapping
	//    resultMappings,ArrayList
        for(Iterator i$ = resultChildren.iterator(); i$.hasNext();)
        {
            XNode resultChild = (XNode)i$.next();
            if("constructor".equals(resultChild.getName()))
	        //constructor     
                processConstructorElement(resultChild, typeClass, resultMappings);
            else
            if("discriminator".equals(resultChild.getName()))
            {
	       //discriminator     
                discriminator = processDiscriminatorElement(resultChild, typeClass, resultMappings);
            } else
            {
	       //result      ,   id   , ResultFlag.ID   flags   
                ArrayList flags = new ArrayList();
                if("id".equals(resultChild.getName()))
                    flags.add(ResultFlag.ID);
                resultMappings.add(buildResultMappingFromContext(resultChild, typeClass, flags));
            }
        }
        //  resultMapResolver
        resultMapResolver = new ResultMapResolver(builderAssistant, id, typeClass, extend, discriminator, resultMappings, autoMapping);
        return resultMapResolver.resolve();
        IncompleteElementException e;
        e;
	//   IncompleteElementException,  resultMapResolver   IncompleteResultMap   
	//LinkedList
        configuration.addIncompleteResultMap(resultMapResolver);
        throw e;
    }
    //  constructor   
 private void processConstructorElement(XNode resultChild, Class resultType, List resultMappings)
        throws Exception
    {
        List argChildren = resultChild.getChildren();
        XNode argChild;
        ArrayList flags;
        for(Iterator i$ = argChildren.iterator(); i$.hasNext(); resultMappings.add(buildResultMappingFromContext(argChild, resultType, flags)))
        {
            argChild = (XNode)i$.next();
            flags = new ArrayList();
            flags.add(ResultFlag.CONSTRUCTOR);
            if("idArg".equals(argChild.getName()))
                flags.add(ResultFlag.ID);
        }

    }
 //  discriminator   
    private Discriminator processDiscriminatorElement(XNode context, Class resultType, List resultMappings)
        throws Exception
    {
        String column = context.getStringAttribute("column");
        String javaType = context.getStringAttribute("javaType");
        String jdbcType = context.getStringAttribute("jdbcType");
        String typeHandler = context.getStringAttribute("typeHandler");
        Class javaTypeClass = resolveClass(javaType);
        Class typeHandlerClass = resolveClass(typeHandler);
        JdbcType jdbcTypeEnum = resolveJdbcType(jdbcType);
        Map discriminatorMap = new HashMap();
        String value;
        String resultMap;
        for(Iterator i$ = context.getChildren().iterator(); i$.hasNext(); discriminatorMap.put(value, resultMap))
        {
            XNode caseChild = (XNode)i$.next();
            value = caseChild.getStringAttribute("value");
            resultMap = caseChild.getStringAttribute("resultMap", processNestedResultMappings(caseChild, resultMappings));
        }

        return builderAssistant.buildDiscriminator(resultType, column, javaTypeClass, jdbcTypeEnum, typeHandlerClass, discriminatorMap);
    }
//result id  ResultMapping  
private ResultMapping buildResultMappingFromContext(XNode context, Class resultType, ArrayList flags)
        throws Exception
    {
        String property = context.getStringAttribute("property");
        String column = context.getStringAttribute("column");
        String javaType = context.getStringAttribute("javaType");
        String jdbcType = context.getStringAttribute("jdbcType");
        String nestedSelect = context.getStringAttribute("select");
        String nestedResultMap = context.getStringAttribute("resultMap", processNestedResultMappings(context, Collections.emptyList()));
        String notNullColumn = context.getStringAttribute("notNullColumn");
        String columnPrefix = context.getStringAttribute("columnPrefix");
        String typeHandler = context.getStringAttribute("typeHandler");
        Class javaTypeClass = resolveClass(javaType);
        Class typeHandlerClass = resolveClass(typeHandler);
        JdbcType jdbcTypeEnum = resolveJdbcType(jdbcType);
        return builderAssistant.buildResultMapping(resultType, property, column, javaTypeClass, jdbcTypeEnum, nestedSelect, nestedResultMap, notNullColumn, columnPrefix, typeHandlerClass, flags);
    }

//  resultMapping
 public ResultMapping buildResultMapping(Class resultType, String property, String column, Class javaType, JdbcType jdbcType, String nestedSelect, String nestedResultMap, 
            String notNullColumn, String columnPrefix, Class typeHandler, List flags)
    {
        ResultMapping resultMapping = assembleResultMapping(resultType, property, column, javaType, jdbcType, nestedSelect, nestedResultMap, notNullColumn, columnPrefix, typeHandler, flags);
        return resultMapping;
    }
  //  ResultMapping
private ResultMapping assembleResultMapping(Class resultType, String property, String column, Class javaType, JdbcType jdbcType, String nestedSelect, String nestedResultMap, 
            String notNullColumn, String columnPrefix, Class typeHandler, List flags)
    {
        Class javaTypeClass = resolveResultJavaType(resultType, property, javaType);
        TypeHandler typeHandlerInstance = resolveTypeHandler(javaTypeClass, typeHandler);
        List composites = parseCompositeColumnName(column);
        if(composites.size() > 0)
            column = null;
        org.apache.ibatis.mapping.ResultMapping.Builder builder = new org.apache.ibatis.mapping.ResultMapping.Builder(configuration, property, column, javaTypeClass);
        builder.jdbcType(jdbcType);
        builder.nestedQueryId(applyCurrentNamespace(nestedSelect, true));
        builder.nestedResultMapId(applyCurrentNamespace(nestedResultMap, true));
        builder.typeHandler(typeHandlerInstance);
        builder.flags(((List) (flags != null ? flags : ((List) (new ArrayList())))));
        builder.composites(composites);
        builder.notNullColumns(parseMultipleColumnNames(notNullColumn));
        builder.columnPrefix(columnPrefix);
        return builder.build();
    }
//ResultMapping
public class ResultMapping
{
    public static class Builder
    {

        public Builder javaType(Class javaType)
        {
            resultMapping.javaType = javaType;
            return this;
        }
	//      resultMapping
	 public ResultMapping build()
        {
            validate();
	    // flag,   unmodifiableList
            resultMapping.flags = Collections.unmodifiableList(resultMapping.flags);
            resultMapping.composites = Collections.unmodifiableList(resultMapping.composites);
            resolveTypeHandler();
            return resultMapping;
        }
	private void resolveTypeHandler()
        {
            if(resultMapping.typeHandler == null && resultMapping.javaType != null)
            {
	        // configuration  typeHandlerRegistry
                Configuration configuration = resultMapping.configuration;
                TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry();
		// typeHandlerRegistry  typeHandler
                resultMapping.typeHandler = typeHandlerRegistry.getTypeHandler(resultMapping.javaType, resultMapping.jdbcType);
            }
        }
	//  builder
	public Builder(Configuration configuration, String property, String column, Class javaType)
        {
            resultMapping = new ResultMapping();
            resultMapping.configuration = configuration;
            resultMapping.property = property;
            resultMapping.column = column;
            resultMapping.javaType = javaType;
            resultMapping.flags = new ArrayList();
            resultMapping.composites = new ArrayList();
        }
}
//ResultFlagG
public final class ResultFlag extends Enum
{

    public static ResultFlag[] values()
    {
        return (ResultFlag[])$VALUES.clone();
    }

    public static ResultFlag valueOf(String name)
    {
        return (ResultFlag)Enum.valueOf(org/apache/ibatis/mapping/ResultFlag, name);
    }

    private ResultFlag(String s, int i)
    {
        super(s, i);
    }

    public static final ResultFlag ID;
    public static final ResultFlag CONSTRUCTOR;
    private static final ResultFlag $VALUES[];

    static 
    {
        ID = new ResultFlag("ID", 0);
        CONSTRUCTOR = new ResultFlag("CONSTRUCTOR", 1);
        $VALUES = (new ResultFlag[] {
            ID, CONSTRUCTOR
        });
    }
}
//ResultMapResolover、ResultMapプロセッサ
public class ResultMapResolver
{
    private final MapperBuilderAssistant assistant;
    private String id;//id  
    private Class type;// type  
    private String extend;
    private Discriminator discriminator;
    private List resultMappings;
    private Boolean autoMapping;

    public ResultMapResolver(MapperBuilderAssistant assistant, String id, Class type, String extend, Discriminator discriminator, List resultMappings, Boolean autoMapping)
    {
        this.assistant = assistant;
        this.id = id;
        this.type = type;
        this.extend = extend;
        this.discriminator = discriminator;
        this.resultMappings = resultMappings;
        this.autoMapping = autoMapping;
    }

    public ResultMap resolve()
    {
        return assistant.addResultMap(id, type, extend, discriminator, resultMappings, autoMapping);
    }
}
//MapperBuilder Asistant
//ResultMapを作成し、ResultMapマッピング関係をconfigrationに追加します。
 public ResultMap addResultMap(String id, Class type, String extend, Discriminator discriminator, List resultMappings, Boolean autoMapping)
    {
         //  ResultMap       
        id = applyCurrentNamespace(id, false);
        extend = applyCurrentNamespace(extend, true);
	//  ResultMap
        org.apache.ibatis.mapping.ResultMap.Builder resultMapBuilder = 
	new org.apache.ibatis.mapping.ResultMap.Builder(configuration, id, type, resultMappings, autoMapping);
        ResultMap resultMap;
        if(extend != null)
        {
	    //       true,  configuration     ResultMap,       IncompleteElementException
            if(!configuration.hasResultMap(extend))
                throw new IncompleteElementException((new StringBuilder()).append("Could not find a parent resultmap with id '").append(extend).append("'").toString());
            resultMap = configuration.getResultMap(extend);
            List extendedResultMappings = new ArrayList(resultMap.getResultMappings());
            extendedResultMappings.removeAll(resultMappings);
            boolean declaresConstructor = false;
            Iterator i$ = resultMappings.iterator();
            do
            {
                if(!i$.hasNext())
                    break;
                ResultMapping resultMapping = (ResultMapping)i$.next();
                if(!resultMapping.getFlags().contains(ResultFlag.CONSTRUCTOR))
                    continue;
                declaresConstructor = true;
                break;
            } while(true);
            if(declaresConstructor)
            {
                Iterator extendedResultMappingsIter = extendedResultMappings.iterator();
                do
                {
                    if(!extendedResultMappingsIter.hasNext())
                        break;
                    if(((ResultMapping)extendedResultMappingsIter.next()).getFlags().contains(ResultFlag.CONSTRUCTOR))
                        extendedResultMappingsIter.remove();
                } while(true);
            }
            resultMappings.addAll(extendedResultMappings);
        }
        resultMapBuilder.discriminator(discriminator);
	//     resultMap
        resultMap = resultMapBuilder.build();
	// resultMap       configuration
        configuration.addResultMap(resultMap);
        return resultMap;
    }
//resultMapマッピング関係をconfigrationに追加する
reult Maps=new StrictMap(「Result Maps collection」);
HashMap,keyはResultMapのグローバルネーム空間idです。

  public void addResultMap(ResultMap rm)
    {
        resultMaps.put(rm.getId(), rm);
        checkLocallyForDiscriminatedNestedResultMaps(rm);
        checkGloballyForDiscriminatedNestedResultMaps(rm);
    }
//ResultMap
public class ResultMap
{
    private String id;
    private Class type;
    private List resultMappings;
    private List idResultMappings;
    private List constructorResultMappings;
    private List propertyResultMappings;
    private Set mappedColumns;
    private Discriminator discriminator;
    private boolean hasNestedResultMaps;
    private boolean hasNestedQueries;
    private Boolean autoMapping;
    public static class Builder
    {
    public ResultMap build()
        {
            if(resultMap.id == null)
                throw new IllegalArgumentException("ResultMaps must have an id");
            resultMap.mappedColumns = new HashSet();
            resultMap.idResultMappings = new ArrayList();
            resultMap.constructorResultMappings = new ArrayList();
            resultMap.propertyResultMappings = new ArrayList();
            Iterator i$ = resultMap.resultMappings.iterator();
            do
            {
                if(!i$.hasNext())
                    break;
                ResultMapping resultMapping = (ResultMapping)i$.next();
                resultMap.hasNestedQueries = resultMap.hasNestedQueries || resultMapping.getNestedQueryId() != null;
                resultMap.hasNestedResultMaps = resultMap.hasNestedResultMaps || resultMapping.getNestedResultMapId() != null;
                String column = resultMapping.getColumn();
                if(column != null)
                    resultMap.mappedColumns.add(column.toUpperCase(Locale.ENGLISH));
                else
                if(resultMapping.isCompositeResult())
                {
                    Iterator i$ = resultMapping.getComposites().iterator();
                    do
                    {
                        if(!i$.hasNext())
                            break;
                        ResultMapping compositeResultMapping = (ResultMapping)i$.next();
                        String compositeColumn = compositeResultMapping.getColumn();
                        if(compositeColumn != null)
                            resultMap.mappedColumns.add(compositeColumn.toUpperCase(Locale.ENGLISH));
                    } while(true);
                }
                if(resultMapping.getFlags().contains(ResultFlag.CONSTRUCTOR))
                    resultMap.constructorResultMappings.add(resultMapping);
                else
                    resultMap.propertyResultMappings.add(resultMapping);
                if(resultMapping.getFlags().contains(ResultFlag.ID))
                    resultMap.idResultMappings.add(resultMapping);
            } while(true);
            if(resultMap.idResultMappings.isEmpty())
                resultMap.idResultMappings.addAll(resultMap.resultMappings);
            resultMap.resultMappings = Collections.unmodifiableList(resultMap.resultMappings);
            resultMap.idResultMappings = Collections.unmodifiableList(resultMap.idResultMappings);
            resultMap.constructorResultMappings = Collections.unmodifiableList(resultMap.constructorResultMappings);
            resultMap.propertyResultMappings = Collections.unmodifiableList(resultMap.propertyResultMappings);
            resultMap.mappedColumns = Collections.unmodifiableSet(resultMap.mappedColumns);
            return resultMap;
        }
   }
}
の から、resultMapノードの が かります。まず、result Mapのid、typeなどの を し、そのサブノードreult、construct、discriminatorを します。resultノードに して、column、property、jdbcTypeなどの を して、ResultMappingに して、result Mappings の でArayListを します。 にレスポンスMapのid、typeなどの と
resultMappingsはResultMapを し、extedの ResultMapが しない は、Incompleete Element Exceptionを り し、configrationに し、Incomplette Result Map-linkedListに する は、 されたconfigrationのreltMapsに まれる。
// sql
sql Element(context.eval Nodes);
//すべてのsqlノードを する
 private void sqlElement(List list)
        throws Exception
    {
        if(configuration.getDatabaseId() != null)
	     //      ,        
            sqlElement(list, configuration.getDatabaseId());
	 //   sqlElement
        sqlElement(list, null);
    }
    //  sql     
    private void sqlElement(List list, String requiredDatabaseId)
        throws Exception
    {
        Iterator i$ = list.iterator();
        do
        {
            if(!i$.hasNext())
                break;
            XNode context = (XNode)i$.next();
	    //  sql  databaseId,id,  
            String databaseId = context.getStringAttribute("databaseId");
            String id = context.getStringAttribute("id");
            id = builderAssistant.applyCurrentNamespace(id, false);
            if(databaseIdMatchesCurrent(id, databaseId, requiredDatabaseId))
	     // sql      sqlFragments-Map ,   select|insert|update|delete   
                sqlFragments.put(id, context);
        } while(true);
    }
   //  sql     requiredDatabaseId    
    private boolean databaseIdMatchesCurrent(String id, String databaseId, String requiredDatabaseId)
    {
        if(requiredDatabaseId != null)
        {
            if(!requiredDatabaseId.equals(databaseId))
                return false;
	 } 
	else
       {
	     if(databaseId != null)
	         return false;
	      //  databaseId requiredDatabaseId  ,   null, 
	      //  configuration sqlFragments       id  sqlFragment  
	      if(sqlFragments.containsKey(id))
	       {
			XNode context = (XNode)sqlFragments.get(id);
			// sql     databaseId   ,  false
			if(context.getStringAttribute("databaseId") != null)
			    return false;
		    }
		}
        return true;
    }
 
から Sqlノードは、SqlノードをXnodeとidマッピング に させ、sql Fragmens-HashMapに することであることが かる。
//select'insert 124 udate statementを する
buildSttement FroomCotext(context.eval Nodes);
//select'insert 124 udateノード の
private void buildStatementFromContext(List list)
    {
        if(configuration.getDatabaseId() != null)
            buildStatementFromContext(list, configuration.getDatabaseId());
	 //   buildStatementFromContext
        buildStatementFromContext(list, null);
    }
    //    select|insert|update|delete    
    private void buildStatementFromContext(List list, String requiredDatabaseId)
    {
        for(Iterator i$ = list.iterator(); i$.hasNext();)
        {
            XNode context = (XNode)i$.next();
	    //  Xnode      XMLStatementBuilder
            XMLStatementBuilder statementParser = new XMLStatementBuilder(configuration, builderAssistant, context, requiredDatabaseId);
            try
            {
	        //  select|insert|update|delete-Xnode  ,   MapStatement,  configuration 
                //mappedStatements Map ,Map
                statementParser.parseStatementNode();
            }
            catch(IncompleteElementException e)
            {
	        //         ,  statementParser   
		//configuration IncompleteStatement   ,LinkedList
                configuration.addIncompleteStatement(statementParser);
            }
        }

    }
//XMLStatement Buider
public class XMLStatementBuilder extends BaseBuilder
{
    public XMLStatementBuilder(Configuration configuration, MapperBuilderAssistant builderAssistant, XNode context)
    {
        this(configuration, builderAssistant, context, null);
    }
    public XMLStatementBuilder(Configuration configuration, MapperBuilderAssistant builderAssistant, XNode context, String databaseId)
    {
        super(configuration);
        this.builderAssistant = builderAssistant;
        this.context = context;
        requiredDatabaseId = databaseId;
    }
    //  Statement XNode  
    public void parseStatementNode()
    {
        //  Statement XNode id,databaseId,fetchSize,timeout,fetchSize,
	//timeout,parameterMap,parameterType,resultMap,resultType,statementType
	//sqlCommandType,flushCache,useCache,resultOrdered,selectKey,keyProperty,keyColumn
        String id = context.getStringAttribute("id");
        String databaseId = context.getStringAttribute("databaseId");
	//  databaseId        requiredDatabaseId  ,     
        if(!databaseIdMatchesCurrent(id, databaseId, requiredDatabaseId))
            return;
        Integer fetchSize = context.getIntAttribute("fetchSize", null);
        Integer timeout = context.getIntAttribute("timeout", null);
        String parameterMap = context.getStringAttribute("parameterMap");
        String parameterType = context.getStringAttribute("parameterType");
        Class parameterTypeClass = resolveClass(parameterType);
        String resultMap = context.getStringAttribute("resultMap");
        String resultType = context.getStringAttribute("resultType");
        String lang = context.getStringAttribute("lang");
        LanguageDriver langDriver = getLanguageDriver(lang);
	//  resultType,  Class
        Class resultTypeClass = resolveClass(resultType);
        String resultSetType = context.getStringAttribute("resultSetType");
	//  statementType  ,   StatementType.PREPARED.toString()
        StatementType statementType = StatementType.valueOf(context.getStringAttribute("statementType", StatementType.PREPARED.toString()));
        ResultSetType resultSetTypeEnum = resolveResultSetType(resultSetType);
        String nodeName = context.getNode().getNodeName();
	//  sqlCommandType  
        SqlCommandType sqlCommandType = SqlCommandType.valueOf(nodeName.toUpperCase(Locale.ENGLISH));
        boolean isSelect = sqlCommandType == SqlCommandType.SELECT;
        boolean flushCache = context.getBooleanAttribute("flushCache", Boolean.valueOf(!isSelect)).booleanValue();
        boolean useCache = context.getBooleanAttribute("useCache", Boolean.valueOf(isSelect)).booleanValue();
        boolean resultOrdered = context.getBooleanAttribute("resultOrdered", Boolean.valueOf(false)).booleanValue();
        XMLIncludeTransformer includeParser = new XMLIncludeTransformer(configuration, builderAssistant);
        includeParser.applyIncludes(context.getNode());
	//  selectKey    
        List selectKeyNodes = context.evalNodes("selectKey");
        if(configuration.getDatabaseId() != null)
            parseSelectKeyNodes(id, selectKeyNodes, parameterTypeClass, langDriver, configuration.getDatabaseId());
        //  SelectKeys  
	parseSelectKeyNodes(id, selectKeyNodes, parameterTypeClass, langDriver, null);
        SqlSource sqlSource = langDriver.createSqlSource(configuration, context, parameterTypeClass);
        String keyProperty = context.getStringAttribute("keyProperty");
        String keyColumn = context.getStringAttribute("keyColumn");
        String keyStatementId = (new StringBuilder()).append(id).append("!selectKey").toString();
	//  selectKey,         id
        keyStatementId = builderAssistant.applyCurrentNamespace(keyStatementId, true);
        KeyGenerator keyGenerator;
	//      keyStatementId   KeyGenerator,   KeyGenerator
        if(configuration.hasKeyGenerator(keyStatementId))
            keyGenerator = configuration.getKeyGenerator(keyStatementId);
        else
	    //    KeyGenerator,
	    //  useGeneratedKeys    ,   true, KeyGenerator Jdbc3KeyGenerator
	    //   useGeneratedKeys     ,        isUseGeneratedKeys SqlCommandType.INSERT
	    //   ,    , KeyGenerator NoKeyGenerator
	    //KeyGenerator     ,         ,         
            keyGenerator = ((KeyGenerator) (context.getBooleanAttribute("useGeneratedKeys", Boolean.valueOf(configuration.isUseGeneratedKeys() && SqlCommandType.INSERT.equals(sqlCommandType))).booleanValue() ? ((KeyGenerator) (new Jdbc3KeyGenerator())) : ((KeyGenerator) (new NoKeyGenerator()))));
        //  select|insert|update|delete       ,  MappedStatement
	//    configuration mappedStatements Map ,Map
	builderAssistant.addMappedStatement(id, sqlSource, statementType, sqlCommandType, fetchSize, timeout, parameterMap, parameterTypeClass, resultMap, resultTypeClass, resultSetTypeEnum, flushCache, useCache, resultOrdered, keyGenerator, keyProperty, keyColumn, databaseId, langDriver);
    }
//SelectKeyノード の
  public void parseSelectKeyNodes(String parentId, List list, Class parameterTypeClass, LanguageDriver langDriver, String skRequiredDatabaseId)
    {
        Iterator i$ = list.iterator();
        do
        {
            if(!i$.hasNext())
                break;
            XNode nodeToHandle = (XNode)i$.next();
            String id = (new StringBuilder()).append(parentId).append("!selectKey").toString();
            String databaseId = nodeToHandle.getStringAttribute("databaseId");
            if(databaseIdMatchesCurrent(id, databaseId, skRequiredDatabaseId))
                parseSelectKeyNode(id, nodeToHandle, parameterTypeClass, langDriver, databaseId);
        } while(true);
    }
//SelectKeyノード を し、 に する
    public void parseSelectKeyNode(String id, XNode nodeToHandle, Class parameterTypeClass, LanguageDriver langDriver, String databaseId)
    {
        //  SelectKey   resultType,keyProperty,statementType,useCache,keyGenerator
	//fetchSize,timeout,flushCache,parameterMap,resultMap     
        String resultType = nodeToHandle.getStringAttribute("resultType");
        Class resultTypeClass = resolveClass(resultType);
        StatementType statementType = StatementType.valueOf(nodeToHandle.getStringAttribute("statementType", StatementType.PREPARED.toString()));
        String keyProperty = nodeToHandle.getStringAttribute("keyProperty");
        boolean executeBefore = "BEFORE".equals(nodeToHandle.getStringAttribute("order", "AFTER"));
        boolean useCache = false;
        boolean resultOrdered = false;
        KeyGenerator keyGenerator = new NoKeyGenerator();
        Integer fetchSize = null;
        Integer timeout = null;
        boolean flushCache = false;
        String parameterMap = null;
        String resultMap = null;
        ResultSetType resultSetTypeEnum = null;
        SqlSource sqlSource = langDriver.createSqlSource(configuration, nodeToHandle, parameterTypeClass);
        SqlCommandType sqlCommandType = SqlCommandType.SELECT;
        // SelectKey       ,  MappedStatement,   
	//configuration mappedStatements Map Map
        builderAssistant.addMappedStatement(id, sqlSource, statementType, sqlCommandType, fetchSize, timeout, parameterMap, parameterTypeClass, resultMap, resultTypeClass, resultSetTypeEnum, flushCache, useCache, resultOrdered, keyGenerator, keyProperty, null, databaseId, langDriver);
        //          
	id = builderAssistant.applyCurrentNamespace(id, false);
	// configuration mappedStatements Map ,  keyStatement
        MappedStatement keyStatement = configuration.getMappedStatement(id, false);
	//  SelectKeyGenerator,    configuration keyGenerators-Map 
        configuration.addKeyGenerator(id, new SelectKeyGenerator(keyStatement, executeBefore));
        nodeToHandle.getParent().getNode().removeChild(nodeToHandle.getNode());
    }
//configration
//keyGeneratorsと のマッピングを してkeyGeneratorsに します。
//keyGenerators:Map
public void addKeyGenerator(String id, KeyGenerator keyGenerator)
    {
        keyGenerators.put(id, keyGenerator);
    }
この に ります
//selectコーディネートノードの に づいて、Mapped Sttementを する
//configrationのmapped SttementsのMapに
Stildesistant. addMappedeSttement(id、sql Source、statementType、sqlCommmadTypee、fetSize、timeout、parameterMap、parameterTypeClass、reultMap、reulttTyypeClass、recucutttttttttCleleclass、OretsesesesesesesesesesesesesesesesecucucucucucucucuttttttttttttttttdedededededededededededededededededededededededededetttttttttttttttttgDriver);
//MapperBuilder Asistant
 public MappedStatement addMappedStatement(String id, SqlSource sqlSource, StatementType statementType, SqlCommandType sqlCommandType, Integer fetchSize, Integer timeout, String parameterMap, 
            Class parameterType, String resultMap, Class resultType, ResultSetType resultSetType, boolean flushCache, boolean useCache, boolean resultOrdered, 
            KeyGenerator keyGenerator, String keyProperty, String keyColumn, String databaseId, LanguageDriver lang)
    {
        if(unresolvedCacheRef)
        {
	    //          ,   IncompleteElementException
            throw new IncompleteElementException("Cache-ref not yet resolved");
        } else
        {
	   //    nameSpace
            id = applyCurrentNamespace(id, false);
            boolean isSelect = sqlCommandType == SqlCommandType.SELECT;
            org.apache.ibatis.mapping.MappedStatement.Builder statementBuilder = new org.apache.ibatis.mapping.MappedStatement.Builder(configuration, id, sqlSource, sqlCommandType);
            statementBuilder.resource(resource);
            statementBuilder.fetchSize(fetchSize);
            statementBuilder.statementType(statementType);
            statementBuilder.keyGenerator(keyGenerator);
            statementBuilder.keyProperty(keyProperty);
            statementBuilder.keyColumn(keyColumn);
            statementBuilder.databaseId(databaseId);
            statementBuilder.lang(lang);
            statementBuilder.resultOrdered(resultOrdered);
            setStatementTimeout(timeout, statementBuilder);
            setStatementParameterMap(parameterMap, parameterType, statementBuilder);
            setStatementResultMap(resultMap, resultType, resultSetType, statementBuilder);
            setStatementCache(isSelect, flushCache, useCache, currentCache, statementBuilder);
	    //  statement     ,  MappedStatement
            MappedStatement statement = statementBuilder.build();
	    // statement,   configuration mappedStatements Map 
            configuration.addMappedStatement(statement);
            return statement;
        }
}
//Mapped Sttement
public final class MappedStatement
{
    private String resource;
    private Configuration configuration;
    private String id;
    private Integer fetchSize;
    private Integer timeout;
    private StatementType statementType;
    private ResultSetType resultSetType;
    private SqlSource sqlSource;
    private Cache cache;
    private ParameterMap parameterMap;
    private List resultMaps;
    private boolean flushCacheRequired;
    private boolean useCache;
    private boolean resultOrdered;
    private SqlCommandType sqlCommandType;
    private KeyGenerator keyGenerator;
    private String keyProperties[];
    private String keyColumns[];
    private boolean hasNestedResultMaps;
    private String databaseId;
    private Log statementLog;
    private LanguageDriver lang;
    //MappedStatement        
    public static class Builder
    {
       public MappedStatement build()
        {
            if(!$assertionsDisabled && mappedStatement.configuration == null)
                throw new AssertionError();
            if(!$assertionsDisabled && mappedStatement.id == null)
                throw new AssertionError();
            if(!$assertionsDisabled && mappedStatement.sqlSource == null)
                throw new AssertionError();
            if(!$assertionsDisabled && mappedStatement.lang == null)
            {
                throw new AssertionError();
            } else
            {
                mappedStatement.resultMaps = Collections.unmodifiableList(mappedStatement.resultMaps);
                return mappedStatement;
            }
        } 
   }
   //    sql    BoundSql
    public BoundSql getBoundSql(Object parameterObject)
    {
        
        BoundSql boundSql = sqlSource.getBoundSql(parameterObject);
        List parameterMappings = boundSql.getParameterMappings();
        if(parameterMappings == null || parameterMappings.size() <= 0)
            boundSql = new BoundSql(configuration, boundSql.getSql(), parameterMap.getParameterMappings(), parameterObject);
        Iterator i$ = boundSql.getParameterMappings().iterator();
        do
        {
            if(!i$.hasNext())
                break;
            ParameterMapping pm = (ParameterMapping)i$.next();
            String rmId = pm.getResultMapId();
            if(rmId != null)
            {
	        //  rmId configuration     ResultMap
                ResultMap rm = configuration.getResultMap(rmId);
                if(rm != null)
		    //  hasNestedResultMaps  
                    hasNestedResultMaps |= rm.hasNestedResultMaps();
            }
        } while(true);
        return boundSql;
    }
}
//BoundSql、sqlの
public class BoundSql
{
    private String sql;
    private List parameterMappings;
    private Object parameterObject;
    private Map additionalParameters;
    private MetaObject metaParameters;

    public BoundSql(Configuration configuration, String sql, List parameterMappings, Object parameterObject)
    {
        this.sql = sql;
        this.parameterMappings = parameterMappings;
        this.parameterObject = parameterObject;
        additionalParameters = new HashMap();
        metaParameters = configuration.newMetaObject(additionalParameters);
    }

    public String getSql()
    {
        return sql;
    }
}
から かるように、 select_insert_udate_Xnode は、まずノード をXMLSTAtement Buiderに し、XMLSTAtement Builderによって され、XMLSTAtement_Builderが すると、statementノードXnodeの キャッシュがExcomplectされていない。XMLStatement BuiderをconfigurationのIncompletSttementセットに し、
Linked List;キャッシュ が されているなら、SelectKeyノード を し、
SelectKeyノードとの を し、configrationのmapped SttementsのMapに し、Mapは、keySttementに づいてSelectKeyGeneratorを し、configrationのkeyGeneratos-Mapに し、SelectKeyノードがない 、SelectKeyノードは、statementノードのuseGenerate edKeys とグローバルプロファイル isUseGeneratodKeysとSql Command Type.INSERTによって するKeyGeneratorが される。statementノードとKeyGeneratorによって、MapperStatimentを し、configrationのmapped SttementのMapに します。
//Mapperを びつける
bindMapper ForNamespace();

 private void bindMapperForNamespace()
    {
        // MapperBuilderAssistant        
        String namespace = builderAssistant.getCurrentNamespace();
        if(namespace != null)
        {
            Class boundType = null;
            try
            {
	       //     namespace   Class
                boundType = Resources.classForName(namespace);
            }
            catch(ClassNotFoundException e) { }
            if(boundType != null && !configuration.hasMapper(boundType))
            {
	        //configuration,     ,   loadedResources Set
                configuration.addLoadedResource((new StringBuilder()).append("namespace:").append(namespace).toString());
                //
		configuration.addMapper(boundType);
            }
        }
    }
//configration、リソース を するloadedResourceのSet
public void addLoadedResource(String resource)
    {
        loadedResources.add(resource);
    }
//mapperRegistry、mapInterfaceを する
 public void addMapper(Class type)
    {
        mapperRegistry.addMapper(type);
    }
//MapperRegistry
 public class MapperRegistry
{
     private Configuration config;
    private final Map knownMappers = new HashMap();
    public MapperRegistry(Configuration config)
    {
        this.config = config;
    }
    public void addMapper(Class type)
    {
        boolean loadCompleted;
        if(!type.isInterface())
            break MISSING_BLOCK_LABEL_125;
        if(hasMapper(type))
            throw new BindingException((new StringBuilder()).append("Type ").append(type).append(" is already known to the MapperRegistry.").toString());
        loadCompleted = false;
        knownMappers.put(type, new MapperProxyFactory(type));
	//  mapInterface,Class config  MapperAnnotationBuilder
        MapperAnnotationBuilder parser = new MapperAnnotationBuilder(config, type);
        parser.parse();
        loadCompleted = true;
        if(!loadCompleted)
            knownMappers.remove(type);
        break MISSING_BLOCK_LABEL_125;
        Exception exception;
        exception;
        if(!loadCompleted)
            knownMappers.remove(type);
        throw exception;
    }
}
//MapperRegistry
public class MapperRegistry
{ public void addMapper(Class type)
    {
        boolean loadCompleted;
        if(!type.isInterface())
            break MISSING_BLOCK_LABEL_125;
        if(hasMapper(type))
            throw new BindingException((new StringBuilder()).append("Type ").append(type).append(" is already known to the MapperRegistry.").toString());
        loadCompleted = false;
	//  Class MapperProxyFactory     
        knownMappers.put(type, new MapperProxyFactory(type));
	//  Mapperclass  Builder 
        MapperAnnotationBuilder parser = new MapperAnnotationBuilder(config, type);
	//    
        parser.parse();
        loadCompleted = true;
        if(!loadCompleted)
            knownMappers.remove(type);
        break MISSING_BLOCK_LABEL_125;
        Exception exception;
        exception;
        if(!loadCompleted)
            knownMappers.remove(type);
        throw exception;
    }
    private Configuration config;
    //HashMap
    private final Map knownMappers = new HashMap();
}
//MapperProxyFactory,mapperInterface     
public class MapperProxyFactory
{
    public MapperProxyFactory(Class mapperInterface)
    {
        methodCache = new ConcurrentHashMap();
        this.mapperInterface = mapperInterface;
    }
     protected Object newInstance(MapperProxy mapperProxy)
    {
        //      
        return Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] {
            mapperInterface
        }, mapperProxy);
    }
    public Object newInstance(SqlSession sqlSession)
    {
        MapperProxy mapperProxy = new MapperProxy(sqlSession, mapperInterface, methodCache);
        return newInstance(mapperProxy);
    }
    private final Class mapperInterface;
    private Map methodCache;
}
//MapperProxy
public class MapperProxy
    implements InvocationHandler, Serializable
{
    public MapperProxy(SqlSession sqlSession, Class mapperInterface, Map methodCache)
    {
        this.sqlSession = sqlSession;
        this.mapperInterface = mapperInterface;
        this.methodCache = methodCache;
    }
    public Object invoke(Object proxy, Method method, Object args[])
        throws Throwable
    {
        if(java/lang/Object.equals(method.getDeclaringClass()))
        {
            return method.invoke(this, args);
        } else
        {
            MapperMethod mapperMethod = cachedMapperMethod(method);
            return mapperMethod.execute(sqlSession, args);
        }
    }
    private MapperMethod cachedMapperMethod(Method method)
    {
        MapperMethod mapperMethod = (MapperMethod)methodCache.get(method);
        if(mapperMethod == null)
        {
            mapperMethod = new MapperMethod(mapperInterface, method, sqlSession.getConfiguration());
            methodCache.put(method, mapperMethod);
        }
        return mapperMethod;
    }

    private static final long serialVersionUID = -6424540398559729838L;
    private final SqlSession sqlSession;
    private final Class mapperInterface;
    //Map,     
    private final Map methodCache;
}
//MapperMethod
public class MapperMethod
{
  //    
  public static class MethodSignature{
	 private final boolean returnsMany;
        private final boolean returnsMap;
        private final boolean returnsVoid;
        private final Class returnType;
        private final String mapKey;
        private final Integer resultHandlerIndex;
        private final Integer rowBoundsIndex;
        private final SortedMap params;
        private final boolean hasNamedParameters;
	public MethodSignature(Configuration configuration, Method method)
            throws BindingException
        {
            returnType = method.getReturnType();
            returnsVoid = Void.TYPE.equals(returnType);
            returnsMany = configuration.getObjectFactory().isCollection(returnType) || returnType.isArray();
            mapKey = getMapKey(method);
            returnsMap = mapKey != null;
            hasNamedParameters = hasNamedParams(method);
            rowBoundsIndex = getUniqueParamIndex(method, org/apache/ibatis/session/RowBounds);
            resultHandlerIndex = getUniqueParamIndex(method, org/apache/ibatis/session/ResultHandler);
            params = Collections.unmodifiableSortedMap(getParams(method, hasNamedParameters));
        }
	}
   //statement  ,SqlCommand
   public static class SqlCommand
    {
        private final String name;
        private final SqlCommandType type;
   }
   //  Map
   public static class ParamMap extends HashMap
    {

        public Object get(Object key)
        {
            if(!super.containsKey(key))
                throw new BindingException((new StringBuilder()).append("Parameter '").append(key).append("' not found. Available parameters are ").append(keySet()).toString());
            else
                return super.get(key);
        }

        private static final long serialVersionUID = -2212268410512043556L;

        public ParamMap()
        {
        }
    }
    //method    
    public Object execute(SqlSession sqlSession, Object args[])
    {
        Object result;
	//  
        if(SqlCommandType.INSERT == command.getType())
        {
	    //      SqlCommand     
            Object param = method.convertArgsToSqlCommandParam(args);
	    //    ,       
            result = rowCountResult(sqlSession.insert(command.getName(), param));
        } else
	//  
        if(SqlCommandType.UPDATE == command.getType())
        {
	    //    ,       
            Object param = method.convertArgsToSqlCommandParam(args);
            result = rowCountResult(sqlSession.update(command.getName(), param));
        } else
	//  
        if(SqlCommandType.DELETE == command.getType())
        {
            //    ,       
            Object param = method.convertArgsToSqlCommandParam(args);
            result = rowCountResult(sqlSession.delete(command.getName(), param));
        } else
	//  
        if(SqlCommandType.SELECT == command.getType())
        {
            if(method.returnsVoid() && method.hasResultHandler())
            {
	        //     
                executeWithResultHandler(sqlSession, args);
                result = null;
            } else
            if(method.returnsMany())
	       //     List
                result = executeForMany(sqlSession, args);
            else
            if(method.returnsMap())
            {
	        //     Map
                result = executeForMap(sqlSession, args);
            } else
            {
	        //     Object
                Object param = method.convertArgsToSqlCommandParam(args);
                result = sqlSession.selectOne(command.getName(), param);
            }
        } else
        {
            throw new BindingException((new StringBuilder()).append("Unknown execution method for: ").append(command.getName()).toString());
        }
        if(result == null && method.getReturnType().isPrimitive() && !method.returnsVoid())
            throw new BindingException((new StringBuilder()).append("Mapper method '").append(command.getName()).append(" attempted to return null from a method with a primitive return type (").append(method.getReturnType()).append(").").toString());
        else
            return result;
    }
    //      
    private Object rowCountResult(int rowCount)
    {
        Object result;
        if(method.returnsVoid())
            result = null;
        else
        if(java/lang/Integer.equals(method.getReturnType()) || Integer.TYPE.equals(method.getReturnType()))
            result = Integer.valueOf(rowCount);
        else
        if(java/lang/Long.equals(method.getReturnType()) || Long.TYPE.equals(method.getReturnType()))
            result = Long.valueOf(rowCount);
        else
        if(java/lang/Boolean.equals(method.getReturnType()) || Boolean.TYPE.equals(method.getReturnType()))
            result = Boolean.valueOf(rowCount > 0);
        else
            throw new BindingException((new StringBuilder()).append("Mapper method '").append(command.getName()).append("' has an unsupported return type: ").append(method.getReturnType()).toString());
        return result;
    }
    //     
     private void executeWithResultHandler(SqlSession sqlSession, Object args[])
    {
        MappedStatement ms = sqlSession.getConfiguration().getMappedStatement(command.getName());
        if(Void.TYPE.equals(((ResultMap)ms.getResultMaps().get(0)).getType()))
            throw new BindingException((new StringBuilder()).append("method ").append(command.getName()).append(" needs either a @ResultMap annotation, a @ResultType annotation,").append(" or a resultType attribute in XML so a ResultHandler can be used as a parameter.").toString());
        Object param = method.convertArgsToSqlCommandParam(args);
        if(method.hasRowBounds())
        {
            RowBounds rowBounds = method.extractRowBounds(args);
            sqlSession.select(command.getName(), param, rowBounds, method.extractResultHandler(args));
        } else
        {
            sqlSession.select(command.getName(), param, method.extractResultHandler(args));
        }
    }
    //     List
    private Object executeForMany(SqlSession sqlSession, Object args[])
    {
        Object param = method.convertArgsToSqlCommandParam(args);
        List result;
        if(method.hasRowBounds())
        {
            RowBounds rowBounds = method.extractRowBounds(args);
            result = sqlSession.selectList(command.getName(), param, rowBounds);
        } else
        {
            result = sqlSession.selectList(command.getName(), param);
        }
        if(!method.getReturnType().isAssignableFrom(result.getClass()))
        {
            if(method.getReturnType().isArray())
                return ((Object) (convertToArray(result)));
            else
                return convertToDeclaredCollection(sqlSession.getConfiguration(), result);
        } else
        {
            return result;
        }
    }
    //     Map
    private Map executeForMap(SqlSession sqlSession, Object args[])
    {
        Object param = method.convertArgsToSqlCommandParam(args);
        Map result;
        if(method.hasRowBounds())
        {
            RowBounds rowBounds = method.extractRowBounds(args);
            result = sqlSession.selectMap(command.getName(), param, method.getMapKey(), rowBounds);
        } else
        {
            result = sqlSession.selectMap(command.getName(), param, method.getMapKey());
        }
        return result;
    }
    private final SqlCommand command;//method,   statement   
    private final MethodSignature method;//    
}
から るとConfigrationにMapperInterfaceを すると、MapperRegistryが されています。
HashMapでは、Mapper ProxyFactoryがMapper Interfaceの です。
MapperInterfaceを するMapperProxyの であり、MapperProxyではMapを し、
キャッシュを します。MapperInterfaceがDMLを するのは、MapperProxyの により、MapperMethodを び す です。
//Resource
public class Resources
{
    public static Class classForName(String className)
        throws ClassNotFoundException
    {
        return classLoaderWrapper.classForName(className);
    }
    private static ClassLoaderWrapper classLoaderWrapper = new ClassLoaderWrapper();
    private static Charset charset;

}
//configrationから のResultMapsを する
parsePendingResultMaps();
private void parsePendingResultMaps()
    {
        Collection incompleteResultMaps = configuration.getIncompleteResultMaps();
        synchronized(incompleteResultMaps)
        {
            for(Iterator iter = incompleteResultMaps.iterator(); iter.hasNext();)
                try
                {
		    //  ResultMap    extend
                    ((ResultMapResolver)iter.next()).resolve();
                    // configuration IncompleteResultMap   
                    iter.remove();
                }
                catch(IncompleteElementException e) { }

        }
    }
//configrationから のCacheRefsを り く
parsePendingChecefs()
private void parsePendingChacheRefs()
    {
        Collection incompleteCacheRefs = configuration.getIncompleteCacheRefs();
        synchronized(incompleteCacheRefs)
        {
            for(Iterator iter = incompleteCacheRefs.iterator(); iter.hasNext();)
                try
                {
		    //CacheRefResolver        configuration      ,
		    //  IncompleteCacheRefs,LinkedList   CacheRefResolver
                    ((CacheRefResolver)iter.next()).resolveCacheRef();
                    iter.remove();
                }
                catch(IncompleteElementException e) { }

        }
    }
//configrationから のSttementsを する
parsePendingSttements()
private void parsePendingStatements()
    {
        Collection incompleteStatements = configuration.getIncompleteStatements();
        synchronized(incompleteStatements)
        {
            for(Iterator iter = incompleteStatements.iterator(); iter.hasNext();)
                try
                {
		    //    statement    ,    incompleteStatements,  
                    ((XMLStatementBuilder)iter.next()).parseStatementNode();
                    iter.remove();
                }
                catch(IncompleteElementException e) { }

        }
    }
まとめ:
Mapper のxmlファイルを すると、 には xmlのmapper Xnode、 にはnamespace 、cache、cache-ref、parameterMap、reult Map、sql、およびselerct insert udateサブノードまで、mapper Xnodeを したら、Maconderectが されます。そしてMapperの を びつけて、 に ったのは、ConfigrationのMapperRegistryを じてMapperRegistryに されたHashMap MapperProxyFactoryはMapperInterfaceのエージェントであり、MapperInterfaceのMapperProxyエージェントの を し、MapperProxyはMapper ProxyでMapを して、Mapper ProxyはMapを して、 にMapperProxyでキャッシュされます。MapperMethodを び す 。その 、 のResultMap、CacheRefs、Sttements タスクを し、 、configrationからIncompleReltMaps、CacheRefs、Sttements Paserからタスクを します。
まとめ:cache-ref: cache-refから、 に、cacheとcache-refの のマッピング をconfigrationに し、configrationからcachef Namespace のCacheを し、cache-refのcachef Namespaceに するキャッシュが しない 、Incomplectement Emplectrotionをスローします。そして するCacheRefResoliverをconfigrationのIncompletCachef にLinklistに します。cache: の からCacheのノードの が られますが、 には、cacheノードのtypeに するクラス、cacheノードのevictに するキャッシュアルゴリズムClass、およびリフレッシュ 、 み き 、CacheBuiderを し、 されたconfigrationの2 キャッシュStrictMapを します。ParameterMap: の からParameterMapの は にParameterMapのid、type とparameterサブノードを することであることが かります。その 、parameterのproperty、javaType、jdbcType、typeHalder、reultMapの を し、これらの に づいてparameterMappingを し、 されたparameterMappings(ArayList)の において; にid、type とparameterMappingsに づいて、ParameterMapを し、configrationのparameterMapsに します。resultMap: の から、resultMapノードの が かります。まず、result Mapのid、typeなどの を して、サブノードのresult、construct、discriminatorを します。resultノードに して、column、property、jdbcTypeなどの を して、ResultMappingに して、result Mappings の でArayListを します。 に、resultMapのid、typeなどの とresultMappingsによってResultMapを し、extedの ResultMapが しない は、Incompplete Element Exceptionを り し、configrationに し、IncompleeteResultMap-linkedListに すれば、 されたMagults。Sql: から SqlノードはSqlノードをXnodeとidマッピング に させてsql Frame nts-HashMapに することであることが かります。select_insert_udate_delete: から かるように、select_insert_124を して、delete-Xnodeの を します。まず、ノード をXMLStatement Buiderに して、XMLSTAtementBuiderによって、 します。XMLStatement BuiderをconfigurationのIncompletSttement に し、Linked List;キャッシュ が されたら、SelectKeyノード とSelectKeyノードの を して、keySttementを し、configrationのmapped SttementのMapに して、Mapは、keySttementに づいてSelectKeyGeneratorを し、configrationのkeyGenerationのkeyGenerators-Mapに して、ノードがない は、Sectry Sectlecty Sectryは、ノードなし。statementノードのuseGenerate edKeys とグローバルプロファイル isUseGeneratodKeysとSql Command Type.INSERTによって するKeyGeneratorが される。statementノードとKeyGeneratorによって、MapperStatimentを し、configrationのmapped SttementのMapに します。
//Sql CommundType
public final class SqlCommandType extends Enum
{
    public static final SqlCommandType UNKNOWN;
    public static final SqlCommandType INSERT;
    public static final SqlCommandType UPDATE;
    public static final SqlCommandType DELETE;
    public static final SqlCommandType SELECT;
    private static final SqlCommandType $VALUES[];
    static 
    {
        UNKNOWN = new SqlCommandType("UNKNOWN", 0);
        INSERT = new SqlCommandType("INSERT", 1);
        UPDATE = new SqlCommandType("UPDATE", 2);
        DELETE = new SqlCommandType("DELETE", 3);
        SELECT = new SqlCommandType("SELECT", 4);
        $VALUES = (new SqlCommandType[] {
            UNKNOWN, INSERT, UPDATE, DELETE, SELECT
        });
    }
}
//Sttement Types
public final class StatementType extends Enum
{
    public static final StatementType STATEMENT;
    public static final StatementType PREPARED;
    public static final StatementType CALLABLE;
    private static final StatementType $VALUES[];
    static 
    {
        STATEMENT = new StatementType("STATEMENT", 0);
        PREPARED = new StatementType("PREPARED", 1);
        CALLABLE = new StatementType("CALLABLE", 2);
        $VALUES = (new StatementType[] {
            STATEMENT, PREPARED, CALLABLE
        });
    }
}