美文网首页
Mybatis:Mapper接口编程原理分析(一)

Mybatis:Mapper接口编程原理分析(一)

作者: 牧呈 | 来源:发表于2018-03-29 20:38 被阅读0次

    获取 Mapper 接口

    • 解析配置文件

      SqlSessionBuilder 接口

    public SqlSessionFactory build(Reader reader, String environment, Properties properties) {
            SqlSessionFactory var5;
            try {
                XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties);
                // 解析 xml 文件
                var5 = this.build(parser.parse());
            } catch (Exception var14) {
                throw ExceptionFactory.wrapException("Error building SqlSession.", var14);
            } finally {
                ErrorContext.instance().reset();
    
                try {
                    reader.close();
                } catch (IOException var13) {
                    ;
                }
    
            }
    
            return var5;
        }
    

    XMLConfigBuilder

    public Configuration parse() {
            // 配置文件只被解析一次
            if (this.parsed) {
                throw new BuilderException("Each XMLConfigBuilder can only be used once.");
            } else {
                this.parsed = true;
                // 解析
                this.parseConfiguration(this.parser.evalNode("/configuration"));
                return this.configuration;
            }
        }
            
    
    private void parseConfiguration(XNode root) {
            try {
                this.propertiesElement(root.evalNode("properties"));
                Properties settings = this.settingsAsProperties(root.evalNode("settings"));
                this.loadCustomVfs(settings);
                this.typeAliasesElement(root.evalNode("typeAliases"));
                this.pluginElement(root.evalNode("plugins"));
                this.objectFactoryElement(root.evalNode("objectFactory"));
                this.objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));
                this.reflectorFactoryElement(root.evalNode("reflectorFactory"));
                this.settingsElement(settings);
                this.environmentsElement(root.evalNode("environments"));
                this.databaseIdProviderElement(root.evalNode("databaseIdProvider"));
                this.typeHandlerElement(root.evalNode("typeHandlers"));
                // 获取 mapper 接口
                this.mapperElement(root.evalNode("mappers"));
            } catch (Exception var3) {
                throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + var3, var3);
            }
        }
    
    private void mapperElement(XNode parent) throws Exception {
            if (parent != null) {
                Iterator var2 = parent.getChildren().iterator();
    
                // mappers 标签配置 mapper 资源的三种方式
                while(true) {
                    while(var2.hasNext()) {
                        XNode child = (XNode)var2.next();
                        String resource;
                        if ("package".equals(child.getName())) {
                            resource = child.getStringAttribute("name");
                            this.configuration.addMappers(resource);
                        } else {
                            resource = child.getStringAttribute("resource");
                            String url = child.getStringAttribute("url");
                            String mapperClass = child.getStringAttribute("class");
                            XMLMapperBuilder mapperParser;
                            InputStream inputStream;
                            if (resource != null && url == null && mapperClass == null) {
                                ErrorContext.instance().resource(resource);
                                inputStream = Resources.getResourceAsStream(resource);
                                mapperParser = new XMLMapperBuilder(inputStream, this.configuration, resource, this.configuration.getSqlFragments());
                                mapperParser.parse();
                            } else if (resource == null && url != null && mapperClass == null) {
                                ErrorContext.instance().resource(url);
                                inputStream = Resources.getUrlAsStream(url);
                                mapperParser = new XMLMapperBuilder(inputStream, this.configuration, url, this.configuration.getSqlFragments());
                                mapperParser.parse();
                            } else {
                                if (resource != null || url != null || mapperClass == null) {
                                    throw new BuilderException("A mapper element may only specify a url, resource or class, but not more than one.");
                                }
    
                                Class<?> mapperInterface = Resources.classForName(mapperClass);
                                // 注册 mapper 接口到 MapperRegistry
                                this.configuration.addMapper(mapperInterface);
                            }
                        }
                    }
    
                    return;
                }
            }
        }
    

    mapper 接口编程首先要获取 mapper 接口信息,因此必须解析配置文件获取 所有 mapper 接口

    • 序列图:


      maper 接口注册

    相关文章

      网友评论

          本文标题:Mybatis:Mapper接口编程原理分析(一)

          本文链接:https://www.haomeiwen.com/subject/cyyvcftx.html