mybatis源码阅读-MappedStatement各个属性解析过程(八)

调用方

类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"元素

org.apache.ibatis.builder.xml.XMLStatementBuilder#parseStatementNode

    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);
        }
    }

 

posted @ 2019-04-13 17:36  意犹未尽  阅读(807)  评论(0编辑  收藏  举报