mybatis-generator源码解读系列(三):配置读取

概述:

        配置读取是代码生成的基础工作,主要就是把xml中的元数据读取到内存中,供后面的代码生成逻辑使用

相关类

1、ConfigurationParser

功能

        主要用来将xml配置文件读取到内存,获取根节点,根据根节点的属性值,选择对应的子节点的配置解析器

代码解读:

1)读取xml

            // dcoument 组装器
            DocumentBuilder builder = factory.newDocumentBuilder();
            builder.setEntityResolver(new ParserEntityResolver());

            // 实例化一个错误处理类,处理的错误和警告信息会以list形式保存
            ParserErrorHandler handler = new ParserErrorHandler(warnings,
                    parseErrors);
            builder.setErrorHandler(handler);
            // 使用w3c 文档解析
            Document document = null;
            try {
            	// 将内存文件转换为w3c文档对象
                document = builder.parse(inputSource);
            } catch (SAXParseException e) {
            	// 抛除自定义xml转换错误异常
                throw new XMLParserException(parseErrors);
            } catch (SAXException e) {
            	// 其他异常处理
                if (e.getException() == null) {
                    parseErrors.add(e.getMessage());
                } else {
                    parseErrors.add(e.getException().getMessage());
                }
            }
             // 有错的情况下,抛出异常终止运行
            if (parseErrors.size() > 0) {
                throw new XMLParserException(parseErrors);
            }

2、解析根节点,根据元数据值获取子节点解析器    

            // 返回的配置文件对象
            Configuration config;
            // 获取根节点 
            Element rootNode = document.getDocumentElement();
            // 获取文档类型 
            DocumentType docType = document.getDoctype();
            if (rootNode.getNodeType() == Node.ELEMENT_NODE
                    && docType.getPublicId().equals(
                            XmlConstants.IBATOR_CONFIG_PUBLIC_ID)) {
                config = parseIbatorConfiguration(rootNode);
            } else if (rootNode.getNodeType() == Node.ELEMENT_NODE
                    && docType.getPublicId().equals(
                            XmlConstants.MYBATIS_GENERATOR_CONFIG_PUBLIC_ID)) {
            	// -//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN
            	// 该DTD运行此分支,也就是mybatis处理分支
                config = parseMyBatisGeneratorConfiguration(rootNode);
            } else {
                throw new XMLParserException(getString("RuntimeError.5")); //$NON-NLS-1$
            }

            if (parseErrors.size() > 0) {
                throw new XMLParserException(parseErrors);
            }

2、MyBatisGeneratorConfigurationParser

功能:

主要实现子节点解析工作,同时把所有的元数据加载到内存,供后续解析使用

代码解读:

1)属性、数据库类驱动以及上下解析    

            if ("properties".equals(childNode.getNodeName())) { //$NON-NLS-1$
                parseProperties(configuration, childNode);
            } else if ("classPathEntry".equals(childNode.getNodeName())) { //$NON-NLS-1$
            	// 转换类路径节点,转换的元素赋值给配置对象
                parseClassPathEntry(configuration, childNode);
            } else if ("context".equals(childNode.getNodeName())) { //$NON-NLS-1$
            	// 转换上下文节点,转换的元素赋值给配置对象
                parseContext(configuration, childNode);
            }
2)解析上下文,将所有的元数据加载到内存上下文,生成代码时使用这些数据(如:生成哪些类、报名、类名等)
        // 获取context的所有属性以及值
        Properties attributes = parseAttributes(node);
        String defaultModelType = attributes.getProperty("defaultModelType"); //$NON-NLS-1$
        String targetRuntime = attributes.getProperty("targetRuntime"); //$NON-NLS-1$
        String introspectedColumnImpl = attributes
                .getProperty("introspectedColumnImpl"); //$NON-NLS-1$
        String id = attributes.getProperty("id"); //$NON-NLS-1$


        ModelType mt = defaultModelType == null ? null : ModelType
                .getModelType(defaultModelType);
        System.err.println("parseContext | 获取缺省的模型类型:" + mt);


        // 实例化一个上下文,并将模型类型传入构造方法,如果为null则是适用condition
        Context context = new Context(mt);
        context.setId(id);
        if (stringHasValue(introspectedColumnImpl)) {
            context.setIntrospectedColumnImpl(introspectedColumnImpl);
        }
        if (stringHasValue(targetRuntime)) {
            context.setTargetRuntime(targetRuntime);
        }


        // 将上下文放到配置对象中
        configuration.addContext(context);


        // 获取上下问的子节点,遍历转换
        NodeList nodeList = node.getChildNodes();
        for (int i = 0; i < nodeList.getLength(); i++) {
            Node childNode = nodeList.item(i);


            if (childNode.getNodeType() != Node.ELEMENT_NODE) {
                continue;
            }


            if ("property".equals(childNode.getNodeName())) { //$NON-NLS-1$
                parseProperty(context, childNode);
            } else if ("plugin".equals(childNode.getNodeName())) { //$NON-NLS-1$
                parsePlugin(context, childNode);
            } else if ("commentGenerator".equals(childNode.getNodeName())) { //$NON-NLS-1$
            	// 注释转换
                parseCommentGenerator(context, childNode);
            } else if ("jdbcConnection".equals(childNode.getNodeName())) { //$NON-NLS-1$
                parseJdbcConnection(context, childNode);
            } else if ("connectionFactory".equals(childNode.getNodeName())) { //$NON-NLS-1$
                parseConnectionFactory(context, childNode);
            } else if ("javaModelGenerator".equals(childNode.getNodeName())) { //$NON-NLS-1$
                parseJavaModelGenerator(context, childNode);
            } else if ("javaTypeResolver".equals(childNode.getNodeName())) { //$NON-NLS-1$
                parseJavaTypeResolver(context, childNode);
            } else if ("sqlMapGenerator".equals(childNode.getNodeName())) { //$NON-NLS-1$
                parseSqlMapGenerator(context, childNode);
            } else if ("javaClientGenerator".equals(childNode.getNodeName())) { //$NON-NLS-1$
                parseJavaClientGenerator(context, childNode);
            } else if ("table".equals(childNode.getNodeName())) { //$NON-NLS-1$
                parseTable(context, childNode);
            }

3)解读每个具体属性到各自内存配置对象中

JavaClientGeneratorConfiguration javaClientGeneratorConfiguration = new JavaClientGeneratorConfiguration();

        context.setJavaClientGeneratorConfiguration(javaClientGeneratorConfiguration);

        Properties attributes = parseAttributes(node);
        String type = attributes.getProperty("type"); //$NON-NLS-1$
        String targetPackage = attributes.getProperty("targetPackage"); //$NON-NLS-1$
        String targetProject = attributes.getProperty("targetProject"); //$NON-NLS-1$
        String implementationPackage = attributes
                .getProperty("implementationPackage"); //$NON-NLS-1$

        javaClientGeneratorConfiguration.setConfigurationType(type);
        javaClientGeneratorConfiguration.setTargetPackage(targetPackage);
        javaClientGeneratorConfiguration.setTargetProject(targetProject);
        javaClientGeneratorConfiguration
                .setImplementationPackage(implementationPackage);

        NodeList nodeList = node.getChildNodes();
        for (int i = 0; i < nodeList.getLength(); i++) {
            Node childNode = nodeList.item(i);

            if (childNode.getNodeType() != Node.ELEMENT_NODE) {
                continue;
            }

            if ("property".equals(childNode.getNodeName())) { //$NON-NLS-1$
                parseProperty(javaClientGeneratorConfiguration, childNode);
            }
        }
※ 上面解读具体解读的代码都雷同,首先需要各自节点的一个配置类( JavaClientGeneratorConfiguration ),然后将数据读取到该类的实例对象中,同时将该对象注入到内存上下文中(Context)。

猜你喜欢

转载自blog.csdn.net/gosenkle/article/details/80678724