src/main/java/com/itfsw/mybatis/generator/plugins/BatchInsertPlugin.java
@Override
    public boolean sqlMapDocumentGenerated(Document document, IntrospectedTable introspectedTable) {
        // 1. batchInsert
        XmlElement batchInsertEle = new XmlElement("insert");
        batchInsertEle.addAttribute(new Attribute("id", METHOD_BATCH_INSERT));
        // 参数类型
        batchInsertEle.addAttribute(new Attribute("parameterType", "map"));
        // 添加注释(!!!必须添加注释，overwrite覆盖生成时，@see XmlFileMergerJaxp.isGeneratedNode会去判断注释中是否存在OLD_ELEMENT_TAGS中的一点，例子：@mbg.generated)
        commentGenerator.addComment(batchInsertEle);

        // 使用JDBC的getGenereatedKeys方法获取主键并赋值到keyProperty设置的领域模型属性中。所以只支持MYSQL和SQLServer
        XmlElementGeneratorTools.useGeneratedKeys(batchInsertEle, introspectedTable);

        batchInsertEle.addElement(new TextElement("insert into " + introspectedTable.getFullyQualifiedTableNameAtRuntime()));
        for (Element element : XmlElementGeneratorTools.generateKeys(ListUtilities.removeIdentityAndGeneratedAlwaysColumns(introspectedTable.getAllColumns()), true)) {
            batchInsertEle.addElement(element);
        }

        // 添加foreach节点
        XmlElement foreachElement = new XmlElement("foreach");
        foreachElement.addAttribute(new Attribute("collection", "list"));
        foreachElement.addAttribute(new Attribute("item", "item"));
        foreachElement.addAttribute(new Attribute("separator", ","));

        for (Element element : XmlElementGeneratorTools.generateValues(ListUtilities.removeIdentityAndGeneratedAlwaysColumns(introspectedTable.getAllColumns()), "item.")) {
            foreachElement.addElement(element);
        }

        // values 构建
        batchInsertEle.addElement(new TextElement("values"));
        batchInsertEle.addElement(foreachElement);
        document.getRootElement().addElement(batchInsertEle);
        logger.debug("itfsw(批量插入插件):" + introspectedTable.getMyBatis3XmlMapperFileName() + "增加batchInsert实现方法。");

        // 2. batchInsertSelective
        XmlElement batchInsertSelectiveEle = new XmlElement("insert");
        // 添加注释(!!!必须添加注释，overwrite覆盖生成时，@see XmlFileMergerJaxp.isGeneratedNode会去判断注释中是否存在OLD_ELEMENT_TAGS中的一点，例子：@mbg.generated)
        commentGenerator.addComment(batchInsertSelectiveEle);

        batchInsertSelectiveEle.addAttribute(new Attribute("id", METHOD_BATCH_INSERT_SELECTIVE));
        // 参数类型
        batchInsertSelectiveEle.addAttribute(new Attribute("parameterType", "map"));

        // 使用JDBC的getGenereatedKeys方法获取主键并赋值到keyProperty设置的领域模型属性中。所以只支持MYSQL和SQLServer
        // issues#70 mybatis 版本升级到3.5.0之后，useGeneratedKeys在配置keyProperty时需要指定前缀
        XmlElementGeneratorTools.useGeneratedKeys(batchInsertSelectiveEle, introspectedTable, PluginTools.compareVersion(mybatisVersion, "3.5.0") >= 0 ? "list." : null);

        // 支持原生字段非空判断
        if (this.allowMultiQueries) {
            XmlElement chooseEle = new XmlElement("choose");

            // selective 增强
            XmlElement selectiveEnhancedEle = new XmlElement("when");
            selectiveEnhancedEle.addAttribute(new Attribute("test", "selective != null and selective.length > 0"));
            chooseEle.addElement(selectiveEnhancedEle);

            selectiveEnhancedEle.getElements().addAll(this.generateSelectiveEnhancedEles(introspectedTable));

            // 原生非空判断语句
            XmlElement selectiveNormalEle = new XmlElement("otherwise");
            chooseEle.addElement(selectiveNormalEle);

            XmlElement foreachEle = new XmlElement("foreach");
            selectiveNormalEle.addElement(foreachEle);
            foreachEle.addAttribute(new Attribute("collection", "list"));
            foreachEle.addAttribute(new Attribute("item", "item"));
            foreachEle.addAttribute(new Attribute("separator", ";"));


            foreachEle.addElement(new TextElement("insert into " + introspectedTable.getFullyQualifiedTableNameAtRuntime()));

            XmlElement insertTrimElement = new XmlElement("trim");
            foreachEle.addElement(insertTrimElement);
            insertTrimElement.addElement(XmlElementGeneratorTools.generateKeysSelective(ListUtilities.removeIdentityAndGeneratedAlwaysColumns(introspectedTable.getAllColumns()), "item."));

            foreachEle.addElement(new TextElement("values"));

            XmlElement valuesTrimElement = new XmlElement("trim");
            foreachEle.addElement(valuesTrimElement);
            valuesTrimElement.addElement(XmlElementGeneratorTools.generateValuesSelective(ListUtilities.removeIdentityAndGeneratedAlwaysColumns(introspectedTable.getAllColumns()), "item."));

            batchInsertSelectiveEle.addElement(chooseEle);
        } else {
            batchInsertSelectiveEle.getElements().addAll(this.generateSelectiveEnhancedEles(introspectedTable));
        }

        document.getRootElement().addElement(batchInsertSelectiveEle);
        logger.debug("itfsw(批量插入插件):" + introspectedTable.getMyBatis3XmlMapperFileName() + "增加batchInsertSelective实现方法。");

        return true;
    }
@Override
    public boolean sqlMapDocumentGenerated(Document document, IntrospectedTable introspectedTable) {
        // 1. batchInsert
        XmlElement batchInsertEle = new XmlElement("insert");
        batchInsertEle.addAttribute(new Attribute("id", METHOD_BATCH_INSERT));
        // 参数类型
        batchInsertEle.addAttribute(new Attribute("parameterType", "map"));
        // 添加注释(!!!必须添加注释，overwrite覆盖生成时，@see XmlFileMergerJaxp.isGeneratedNode会去判断注释中是否存在OLD_ELEMENT_TAGS中的一点，例子：@mbg.generated)
        commentGenerator.addComment(batchInsertEle);

        // 使用JDBC的getGenereatedKeys方法获取主键并赋值到keyProperty设置的领域模型属性中。所以只支持MYSQL和SQLServer
        XmlElementGeneratorTools.useGeneratedKeys(batchInsertEle, introspectedTable);

        batchInsertEle.addElement(new TextElement("insert into " + introspectedTable.getFullyQualifiedTableNameAtRuntime()));
        for (Element element : XmlElementGeneratorTools.generateKeys(ListUtilities.removeIdentityAndGeneratedAlwaysColumns(introspectedTable.getAllColumns()), true)) {
            batchInsertEle.addElement(element);
        }

        // 添加foreach节点
        XmlElement foreachElement = new XmlElement("foreach");
        foreachElement.addAttribute(new Attribute("collection", "list"));
        foreachElement.addAttribute(new Attribute("item", "item"));
        foreachElement.addAttribute(new Attribute("separator", ","));

        for (Element element : XmlElementGeneratorTools.generateValues(ListUtilities.removeIdentityAndGeneratedAlwaysColumns(introspectedTable.getAllColumns()), "item.")) {
            foreachElement.addElement(element);
        }

        // values 构建
        batchInsertEle.addElement(new TextElement("values"));
        batchInsertEle.addElement(foreachElement);
        document.getRootElement().addElement(batchInsertEle);
        logger.debug("itfsw(批量插入插件):" + introspectedTable.getMyBatis3XmlMapperFileName() + "增加batchInsert实现方法。");

        // 2. batchInsertSelective
        XmlElement batchInsertSelectiveEle = new XmlElement("insert");
        // 添加注释(!!!必须添加注释，overwrite覆盖生成时，@see XmlFileMergerJaxp.isGeneratedNode会去判断注释中是否存在OLD_ELEMENT_TAGS中的一点，例子：@mbg.generated)
        commentGenerator.addComment(batchInsertSelectiveEle);

        batchInsertSelectiveEle.addAttribute(new Attribute("id", METHOD_BATCH_INSERT_SELECTIVE));
        // 参数类型
        batchInsertSelectiveEle.addAttribute(new Attribute("parameterType", "map"));

        // 使用JDBC的getGenereatedKeys方法获取主键并赋值到keyProperty设置的领域模型属性中。所以只支持MYSQL和SQLServer
        // issues#70 mybatis 版本升级到3.5.0之后，useGeneratedKeys在配置keyProperty时需要指定前缀
        XmlElementGeneratorTools.useGeneratedKeys(batchInsertSelectiveEle, introspectedTable, PluginTools.compareVersion(mybatisVersion, "3.5.0") >= 0 ? "list." : null);

        // 支持原生字段非空判断
        if (this.allowMultiQueries) {
            XmlElement chooseEle = new XmlElement("choose");

            // selective 增强
            XmlElement selectiveEnhancedEle = new XmlElement("when");
            selectiveEnhancedEle.addAttribute(new Attribute("test", "selective != null and selective.length > 0"));
            chooseEle.addElement(selectiveEnhancedEle);

            selectiveEnhancedEle.getElements().addAll(this.generateSelectiveEnhancedEles(introspectedTable));

            // 原生非空判断语句
            XmlElement selectiveNormalEle = new XmlElement("otherwise");
            chooseEle.addElement(selectiveNormalEle);

            XmlElement foreachEle = new XmlElement("foreach");
            selectiveNormalEle.addElement(foreachEle);
            foreachEle.addAttribute(new Attribute("collection", "list"));
            foreachEle.addAttribute(new Attribute("item", "item"));
            foreachEle.addAttribute(new Attribute("separator", ";"));


            foreachEle.addElement(new TextElement("insert into " + introspectedTable.getFullyQualifiedTableNameAtRuntime()));

            XmlElement insertTrimElement = new XmlElement("trim");
            foreachEle.addElement(insertTrimElement);
            insertTrimElement.addElement(XmlElementGeneratorTools.generateKeysSelective(ListUtilities.removeIdentityAndGeneratedAlwaysColumns(introspectedTable.getAllColumns()), "item."));

            foreachEle.addElement(new TextElement("values"));

            XmlElement valuesTrimElement = new XmlElement("trim");
            foreachEle.addElement(valuesTrimElement);
            valuesTrimElement.addElement(XmlElementGeneratorTools.generateValuesSelective(ListUtilities.removeIdentityAndGeneratedAlwaysColumns(introspectedTable.getAllColumns()), "item."));

            batchInsertSelectiveEle.addElement(chooseEle);
        } else {
            batchInsertSelectiveEle.getElements().addAll(this.generateSelectiveEnhancedEles(introspectedTable));
        }

        document.getRootElement().addElement(batchInsertSelectiveEle);
        logger.debug("itfsw(批量插入插件):" + introspectedTable.getMyBatis3XmlMapperFileName() + "增加batchInsertSelective实现方法。");

        return true;
    }
SQL Map Methods 生成
具体执行顺序 http://www.mybatis.org/generator/reference/pluggingIn.html
@param document
@param introspectedTable
@return