src/main/java/com/itfsw/mybatis/generator/plugins/UpsertPlugin.java
private void generateXmlElement(Document document, IntrospectedTable introspectedTable, boolean withBLOBs) {
        List<IntrospectedColumn> columns = ListUtilities.removeGeneratedAlwaysColumns(withBLOBs ? introspectedTable.getAllColumns() : introspectedTable.getNonBLOBColumns());
        // ====================================== upsert ======================================
        XmlElement insertEle = new XmlElement("insert");
        insertEle.addAttribute(new Attribute("id", withBLOBs ? METHOD_UPSERT_WITH_BLOBS : METHOD_UPSERT));
        // 添加注释(!!!必须添加注释，overwrite覆盖生成时，@see XmlFileMergerJaxp.isGeneratedNode会去判断注释中是否存在OLD_ELEMENT_TAGS中的一点，例子：@mbg.generated)
        commentGenerator.addComment(insertEle);

        // 参数类型
        insertEle.addAttribute(new Attribute("parameterType",
                withBLOBs ? JavaElementGeneratorTools.getModelTypeWithBLOBs(introspectedTable).getFullyQualifiedName() : JavaElementGeneratorTools.getModelTypeWithoutBLOBs(introspectedTable).getFullyQualifiedName()
        ));

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

        // insert
        insertEle.addElement(new TextElement("insert into " + introspectedTable.getFullyQualifiedTableNameAtRuntime()));
        for (Element element : XmlElementGeneratorTools.generateUpsertKeys(columns, null)) {
            insertEle.addElement(element);
        }
        insertEle.addElement(new TextElement("values"));
        for (Element element : XmlElementGeneratorTools.generateUpsertValues(columns, null, true)) {
            insertEle.addElement(element);
        }
        insertEle.addElement(new TextElement("on duplicate key update "));
        // set
        for (Element set : XmlElementGeneratorTools.generateUpsertSets(columns, null)) {
            insertEle.addElement(set);
        }

        document.getRootElement().addElement(insertEle);
        logger.debug("itfsw(存在即更新插件):" + introspectedTable.getMyBatis3XmlMapperFileName() + "增加" + (withBLOBs ? "upsertWithBLOBs" : "upsert") + "实现方法。");

        if (this.allowMultiQueries) {
            // ====================================== upsertByExample ======================================
            XmlElement updateEle = new XmlElement("update");
            updateEle.addAttribute(new Attribute("id", withBLOBs ? METHOD_UPSERT_BY_EXAMPLE_WITH_BLOBS : METHOD_UPSERT_BY_EXAMPLE));
            // 参数类型
            updateEle.addAttribute(new Attribute("parameterType", "map"));
            // 添加注释(!!!必须添加注释，overwrite覆盖生成时，@see XmlFileMergerJaxp.isGeneratedNode会去判断注释中是否存在OLD_ELEMENT_TAGS中的一点，例子：@mbg.generated)
            commentGenerator.addComment(updateEle);

            // 使用JDBC的getGenereatedKeys方法获取主键并赋值到keyProperty设置的领域模型属性中。所以只支持MYSQL和SQLServer
            // XmlElementGeneratorTools.useGeneratedKeys(updateEle, introspectedTable, "record.");
            // upsertByExample 先执行的update，所以没法获取id

            // update
            updateEle.addElement(new TextElement("update " + introspectedTable.getAliasedFullyQualifiedTableNameAtRuntime()));
            updateEle.addElement(new TextElement("set"));
            // set
            for (Element set : XmlElementGeneratorTools.generateUpsertSets(columns, "record.")) {
                updateEle.addElement(set);
            }

            // update where
            updateEle.addElement(XmlElementGeneratorTools.getUpdateByExampleIncludeElement(introspectedTable));

            // multiQueries
            updateEle.addElement(new TextElement(";"));

            // insert
            updateEle.addElement(new TextElement("insert into " + introspectedTable.getFullyQualifiedTableNameAtRuntime()));
            for (Element element : XmlElementGeneratorTools.generateUpsertKeys(columns, "record.")) {
                updateEle.addElement(element);
            }
            this.generateExistsClause(introspectedTable, updateEle, XmlElementGeneratorTools.generateUpsertValues(columns, "record.", false));

            document.getRootElement().addElement(updateEle);
            logger.debug("itfsw(存在即更新插件):" + introspectedTable.getMyBatis3XmlMapperFileName() + "增加" + (withBLOBs ? "upsertByExampleWithBLOBs" : "upsertByExample") + "实现方法。");
        }
    }
private void generateXmlElement(Document document, IntrospectedTable introspectedTable, boolean withBLOBs) {
        List<IntrospectedColumn> columns = ListUtilities.removeGeneratedAlwaysColumns(withBLOBs ? introspectedTable.getAllColumns() : introspectedTable.getNonBLOBColumns());
        // ====================================== upsert ======================================
        XmlElement insertEle = new XmlElement("insert");
        insertEle.addAttribute(new Attribute("id", withBLOBs ? METHOD_UPSERT_WITH_BLOBS : METHOD_UPSERT));
        // 添加注释(!!!必须添加注释，overwrite覆盖生成时，@see XmlFileMergerJaxp.isGeneratedNode会去判断注释中是否存在OLD_ELEMENT_TAGS中的一点，例子：@mbg.generated)
        commentGenerator.addComment(insertEle);

        // 参数类型
        insertEle.addAttribute(new Attribute("parameterType",
                withBLOBs ? JavaElementGeneratorTools.getModelTypeWithBLOBs(introspectedTable).getFullyQualifiedName() : JavaElementGeneratorTools.getModelTypeWithoutBLOBs(introspectedTable).getFullyQualifiedName()
        ));

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

        // insert
        insertEle.addElement(new TextElement("insert into " + introspectedTable.getFullyQualifiedTableNameAtRuntime()));
        for (Element element : XmlElementGeneratorTools.generateUpsertKeys(columns, null)) {
            insertEle.addElement(element);
        }
        insertEle.addElement(new TextElement("values"));
        for (Element element : XmlElementGeneratorTools.generateUpsertValues(columns, null, true)) {
            insertEle.addElement(element);
        }
        insertEle.addElement(new TextElement("on duplicate key update "));
        // set
        for (Element set : XmlElementGeneratorTools.generateUpsertSets(columns, null)) {
            insertEle.addElement(set);
        }

        document.getRootElement().addElement(insertEle);
        logger.debug("itfsw(存在即更新插件):" + introspectedTable.getMyBatis3XmlMapperFileName() + "增加" + (withBLOBs ? "upsertWithBLOBs" : "upsert") + "实现方法。");

        if (this.allowMultiQueries) {
            // ====================================== upsertByExample ======================================
            XmlElement updateEle = new XmlElement("update");
            updateEle.addAttribute(new Attribute("id", withBLOBs ? METHOD_UPSERT_BY_EXAMPLE_WITH_BLOBS : METHOD_UPSERT_BY_EXAMPLE));
            // 参数类型
            updateEle.addAttribute(new Attribute("parameterType", "map"));
            // 添加注释(!!!必须添加注释，overwrite覆盖生成时，@see XmlFileMergerJaxp.isGeneratedNode会去判断注释中是否存在OLD_ELEMENT_TAGS中的一点，例子：@mbg.generated)
            commentGenerator.addComment(updateEle);

            // 使用JDBC的getGenereatedKeys方法获取主键并赋值到keyProperty设置的领域模型属性中。所以只支持MYSQL和SQLServer
            // XmlElementGeneratorTools.useGeneratedKeys(updateEle, introspectedTable, "record.");
            // upsertByExample 先执行的update，所以没法获取id

            // update
            updateEle.addElement(new TextElement("update " + introspectedTable.getAliasedFullyQualifiedTableNameAtRuntime()));
            updateEle.addElement(new TextElement("set"));
            // set
            for (Element set : XmlElementGeneratorTools.generateUpsertSets(columns, "record.")) {
                updateEle.addElement(set);
            }

            // update where
            updateEle.addElement(XmlElementGeneratorTools.getUpdateByExampleIncludeElement(introspectedTable));

            // multiQueries
            updateEle.addElement(new TextElement(";"));

            // insert
            updateEle.addElement(new TextElement("insert into " + introspectedTable.getFullyQualifiedTableNameAtRuntime()));
            for (Element element : XmlElementGeneratorTools.generateUpsertKeys(columns, "record.")) {
                updateEle.addElement(element);
            }
            this.generateExistsClause(introspectedTable, updateEle, XmlElementGeneratorTools.generateUpsertValues(columns, "record.", false));

            document.getRootElement().addElement(updateEle);
            logger.debug("itfsw(存在即更新插件):" + introspectedTable.getMyBatis3XmlMapperFileName() + "增加" + (withBLOBs ? "upsertByExampleWithBLOBs" : "upsertByExample") + "实现方法。");
        }
    }
生成xml
@param document
@param introspectedTable
@param withBLOBs