zoukankan      html  css  js  c++  java
  • 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"元素

        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);
            }
        }
  • 相关阅读:
    [Erlang 0116] 当我们谈论Erlang Maps时,我们谈论什么 Part 1
    致鸡鸣狗盗
    一个技术人的知识管理方法论
    一碗清酒聚知音 我看 《少年黄飞鸿-铁马骝》
    [Erlang 0115] 2014值得期待的Erlang两本新书
    [Erlang 0114] Erlang Resources 小站 2013年7月~12月资讯合集
    我的2013 Q.E.D
    Elixir
    [Erlang 0113] Elixir 编译流程梳理
    [Erlang 0112] Elixir Protocols
  • 原文地址:https://www.cnblogs.com/LQBlog/p/10702063.html
Copyright © 2011-2022 走看看