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);
            }
        }
  • 相关阅读:
    Codeforces 1255B Fridge Lockers
    Codeforces 1255A Changing Volume
    Codeforces 1255A Changing Volume
    leetcode 112. 路径总和
    leetcode 129. 求根到叶子节点数字之和
    leetcode 404. 左叶子之和
    leetcode 104. 二叉树的最大深度
    leetcode 235. 二叉搜索树的最近公共祖先
    450. Delete Node in a BST
    树的c++实现--建立一棵树
  • 原文地址:https://www.cnblogs.com/LQBlog/p/10702063.html
Copyright © 2011-2022 走看看