1. 程式人生 > >mybatis源碼閱讀-MappedStatement各個屬性解析過程(八)

mybatis源碼閱讀-MappedStatement各個屬性解析過程(八)

是否 eterm empty ann instance ref int arraylist ngs

調用方

類org.apache.ibatis.builder.xml.XMLMapperBuilder
   private void configurationElement(XNode context) {
        try {
            String namespace = context.getStringAttribute("namespace");
            if (namespace != null && !namespace.equals("")) {
                this.builderAssistant.setCurrentNamespace(namespace);
                
this.cacheRefElement(context.evalNode("cache-ref")); this.cacheElement(context.evalNode("cache")); this.parameterMapElement(context.evalNodes("/mapper/parameterMap")); this.resultMapElements(context.evalNodes("/mapper/resultMap")); this
.sqlElement(context.evalNodes("/mapper/sql")); this.buildStatementFromContext(context.evalNodes("select|insert|update|delete")); } else { throw new BuilderException("Mapper‘s namespace cannot be empty"); } } catch (Exception var3) {
throw new BuilderException("Error parsing Mapper XML. Cause: " + var3, var3); } }

解析ParameterMap

表現形式

<parameterMap class="com.ibatis.dataobject.Product" id="insert-product-param" >  
        <parameter property="id"/>  
        <parameter property="description"/>  
        <parameter property="price"/>       
</parameterMap>  
<statement id="insertProduct-useParaMap" parameterMap="insert-product-param">  
        <![CDATA[insert into t_product(prd_id,prd_description,prd_price) values(?,?,?)]]>  
</statement>  

源碼

 private void parameterMapElement(List<XNode> list) throws Exception {
        Iterator i$ = list.iterator();

        //循環解析所有ParameterMap
        while(i$.hasNext()) {
            XNode parameterMapNode = (XNode)i$.next();
            String id = parameterMapNode.getStringAttribute("id");
            String type = parameterMapNode.getStringAttribute("type");
            Class<?> parameterClass = this.resolveClass(type);
            List<XNode> parameterNodes = parameterMapNode.evalNodes("parameter");
            List<ParameterMapping> parameterMappings = new ArrayList();
           
            Iterator i$ = parameterNodes.iterator();
            //解析裏面的parameter節點封裝成parameterMapping對象
            while(i$.hasNext()) {
                XNode parameterNode = (XNode)i$.next();
                String property = parameterNode.getStringAttribute("property");
                String javaType = parameterNode.getStringAttribute("javaType");
                String jdbcType = parameterNode.getStringAttribute("jdbcType");
                String resultMap = parameterNode.getStringAttribute("resultMap");
                String mode = parameterNode.getStringAttribute("mode");
                String typeHandler = parameterNode.getStringAttribute("typeHandler");
                Integer numericScale = parameterNode.getIntAttribute("numericScale");
                ParameterMode modeEnum = this.resolveParameterMode(mode);
                Class<?> javaTypeClass = this.resolveClass(javaType);
                JdbcType jdbcTypeEnum = this.resolveJdbcType(jdbcType);
                Class<? extends TypeHandler<?>> typeHandlerClass = this.resolveClass(typeHandler);
                ParameterMapping parameterMapping = this.builderAssistant.buildParameterMapping(parameterClass, property, javaTypeClass, jdbcTypeEnum, resultMap, modeEnum, typeHandlerClass, numericScale);
                parameterMappings.add(parameterMapping);
            }
            //內部創建成ParameterMap對象 將parameterMappings設置到屬性裏面
            this.builderAssistant.addParameterMap(id, parameterClass, parameterMappings);
        }

    }
    public ParameterMap addParameterMap(String id, Class<?> parameterClass, List<ParameterMapping> parameterMappings) {
        id = this.applyCurrentNamespace(id, false);
        //創建ParameterMap並添加到configuration
        ParameterMap parameterMap = (new ParameterMap.Builder(this.configuration, id, parameterClass, parameterMappings)).build();
        this.configuration.addParameterMap(parameterMap);
        return parameterMap;
    }

解析ResultMap

跟paramterMap解析很相似 但是resultMap有extend功能

表現形式

    <resultMap id="simpleType" type="com.liqiang.entity.Classes">
        <id property="id" column="id" />

    </resultMap>
    <resultMap id="studentMap" type="com.liqiang.entity.Classes" extends="simpleType">
        <result property="name" column="name" />
    </resultMap>

源碼

    private ResultMap resultMapElement(XNode resultMapNode, List<ResultMapping> additionalResultMappings) throws Exception {
        ErrorContext.instance().activity("processing " + resultMapNode.getValueBasedIdentifier());
        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");
        Class<?> typeClass = this.resolveClass(type);
        Discriminator discriminator = null;
        List<ResultMapping> resultMappings = new ArrayList();
        resultMappings.addAll(additionalResultMappings);
        List<XNode> resultChildren = resultMapNode.getChildren();
        Iterator i$ = resultChildren.iterator();

        while(i$.hasNext()) {
            XNode resultChild = (XNode)i$.next();
            if ("constructor".equals(resultChild.getName())) {
                this.processConstructorElement(resultChild, typeClass, resultMappings);
            } else if ("discriminator".equals(resultChild.getName())) {
                discriminator = this.processDiscriminatorElement(resultChild, typeClass, resultMappings);
            } else {
                List<ResultFlag> flags = new ArrayList();
                if ("id".equals(resultChild.getName())) {
                    flags.add(ResultFlag.ID);
                }

                resultMappings.add(this.buildResultMappingFromContext(resultChild, typeClass, flags));
            }
        }
         //內部會解析將extend的標簽元素整合進來創建一個新的resultMap
        ResultMapResolver resultMapResolver = new ResultMapResolver(this.builderAssistant, id, typeClass, extend, discriminator, resultMappings, autoMapping);

        try {
            return resultMapResolver.resolve();
        } catch (IncompleteElementException var14) {
            this.configuration.addIncompleteResultMap(resultMapResolver);
            throw var14;
        }
    }

解析"select|insert|update|delete"元素

    public void parseStatementNode() {
        String id = this.context.getStringAttribute("id");
        String databaseId = this.context.getStringAttribute("databaseId");
        if (this.databaseIdMatchesCurrent(id, databaseId, this.requiredDatabaseId)) {
            Integer fetchSize = this.context.getIntAttribute("fetchSize");
            Integer timeout = this.context.getIntAttribute("timeout");
            String parameterMap = this.context.getStringAttribute("parameterMap");
            String parameterType = this.context.getStringAttribute("parameterType");
            Class<?> parameterTypeClass = this.resolveClass(parameterType);
            String resultMap = this.context.getStringAttribute("resultMap");
            String resultType = this.context.getStringAttribute("resultType");
            String lang = this.context.getStringAttribute("lang");
            LanguageDriver langDriver = this.getLanguageDriver(lang);
            Class<?> resultTypeClass = this.resolveClass(resultType);
            String resultSetType = this.context.getStringAttribute("resultSetType");
            StatementType statementType = StatementType.valueOf(this.context.getStringAttribute("statementType", StatementType.PREPARED.toString()));
            ResultSetType resultSetTypeEnum = this.resolveResultSetType(resultSetType);
            String nodeName = this.context.getNode().getNodeName();
            SqlCommandType sqlCommandType = SqlCommandType.valueOf(nodeName.toUpperCase(Locale.ENGLISH));
            boolean isSelect = sqlCommandType == SqlCommandType.SELECT;
            boolean flushCache = this.context.getBooleanAttribute("flushCache", !isSelect).booleanValue();
            boolean useCache = this.context.getBooleanAttribute("useCache", isSelect).booleanValue();
            boolean resultOrdered = this.context.getBooleanAttribute("resultOrdered", false).booleanValue();
            XMLIncludeTransformer includeParser = new XMLIncludeTransformer(this.configuration, this.builderAssistant);
            includeParser.applyIncludes(this.context.getNode());
            this.processSelectKeyNodes(id, parameterTypeClass, langDriver);
            SqlSource sqlSource = langDriver.createSqlSource(this.configuration, this.context, parameterTypeClass);
            String resultSets = this.context.getStringAttribute("resultSets");
            String keyProperty = this.context.getStringAttribute("keyProperty");
            String keyColumn = this.context.getStringAttribute("keyColumn");
            String keyStatementId = id + "!selectKey";
            keyStatementId = this.builderAssistant.applyCurrentNamespace(keyStatementId, true);
            Object keyGenerator;
            if (this.configuration.hasKeyGenerator(keyStatementId)) {
                keyGenerator = this.configuration.getKeyGenerator(keyStatementId);
            } else {
                keyGenerator = this.context.getBooleanAttribute("useGeneratedKeys", this.configuration.isUseGeneratedKeys() && SqlCommandType.INSERT.equals(sqlCommandType)).booleanValue() ? new Jdbc3KeyGenerator() : new NoKeyGenerator();
            }
            //最終根據namesppace+id為key封裝成MappedStatement保存到Configuration
            this.builderAssistant.addMappedStatement(id, sqlSource, statementType, sqlCommandType, fetchSize, timeout, parameterMap, parameterTypeClass, resultMap, resultTypeClass, resultSetTypeEnum, flushCache, useCache, resultOrdered, (KeyGenerator)keyGenerator, keyProperty, keyColumn, databaseId, langDriver, resultSets);
        }
    }

mybatis源碼閱讀-MappedStatement各個屬性解析過程(八)