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

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

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

        // insert
        insertEle.addElement(new TextElement("insert into " + introspectedTable.getFullyQualifiedTableNameAtRuntime()));
        for (Element element : XmlElementGeneratorTools.generateKeys(columns, true)) {
            insertEle.addElement(element);
        }
        insertEle.addElement(new TextElement("values"));

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

        for (Element element : XmlElementGeneratorTools.generateValues(columns, "item.", true)) {
            foreachEle.addElement(element);
        }
        insertEle.addElement(new TextElement("on duplicate key update "));
        // set
        Iterator<IntrospectedColumn> columnIterator = columns.iterator();
        while (columnIterator.hasNext()) {
            IntrospectedColumn column = columnIterator.next();
            insertEle.addElement(new TextElement(
                    MyBatis3FormattingUtilities.getEscapedColumnName(column)
                            + " = values(" + MyBatis3FormattingUtilities.getEscapedColumnName(column)
                            + ")"
                            + (columnIterator.hasNext() ? "," : "")
            ));
        }

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

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

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

        // insert
        insertEle.addElement(new TextElement("insert into " + introspectedTable.getFullyQualifiedTableNameAtRuntime()));
        for (Element element : XmlElementGeneratorTools.generateKeys(columns, true)) {
            insertEle.addElement(element);
        }
        insertEle.addElement(new TextElement("values"));

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

        for (Element element : XmlElementGeneratorTools.generateValues(columns, "item.", true)) {
            foreachEle.addElement(element);
        }
        insertEle.addElement(new TextElement("on duplicate key update "));
        // set
        Iterator<IntrospectedColumn> columnIterator = columns.iterator();
        while (columnIterator.hasNext()) {
            IntrospectedColumn column = columnIterator.next();
            insertEle.addElement(new TextElement(
                    MyBatis3FormattingUtilities.getEscapedColumnName(column)
                            + " = values(" + MyBatis3FormattingUtilities.getEscapedColumnName(column)
                            + ")"
                            + (columnIterator.hasNext() ? "," : "")
            ));
        }

        document.getRootElement().addElement(insertEle);
        logger.debug("itfsw(存在即更新插件):" + introspectedTable.getMyBatis3XmlMapperFileName() + "增加" + (withBLOBs ? "batchUpsertWithBLOBs" : "batchUpsert") + "实现方法。");
    }
private void generateBatchXmlElement ( Document document , IntrospectedTable introspectedTable , boolean withBLOBs ) { List < IntrospectedColumn > columns = ListUtilities . removeGeneratedAlwaysColumns ( withBLOBs ? introspectedTable . getAllColumns ( ) : introspectedTable . getNonBLOBColumns ( ) ) ; XmlElement insertEle = new XmlElement ( "insert" ) ; insertEle . addAttribute ( new Attribute ( "id" , withBLOBs ? METHOD_BATCH_UPSERT_WITH_BLOBS : METHOD_BATCH_UPSERT ) ) ; // 添加注释(!!!必须添加注释，overwrite覆盖生成时，@see XmlFileMergerJaxp.isGeneratedNode会去判断注释中是否存在OLD_ELEMENT_TAGS中的一点，例子：@mbg.generated) commentGenerator . addComment ( insertEle ) ; // 参数类型 insertEle . addAttribute ( new Attribute ( "parameterType" , "map" ) ) ; // 使用JDBC的getGenereatedKeys方法获取主键并赋值到keyProperty设置的领域模型属性中。所以只支持MYSQL和SQLServer // XmlElementGeneratorTools.useGeneratedKeys(insertEle, introspectedTable); // insert insertEle . addElement ( new TextElement ( "insert into " + introspectedTable . getFullyQualifiedTableNameAtRuntime ( ) ) ) ; for ( Element element : XmlElementGeneratorTools . generateKeys ( columns , true ) ) { insertEle . addElement ( element ) ; } insertEle . addElement ( new TextElement ( "values" ) ) ; // values XmlElement foreachEle = new XmlElement ( "foreach" ) ; insertEle . addElement ( foreachEle ) ; foreachEle . addAttribute ( new Attribute ( "collection" , "list" ) ) ; foreachEle . addAttribute ( new Attribute ( "item" , "item" ) ) ; foreachEle . addAttribute ( new Attribute ( "separator" , "," ) ) ; for ( Element element : XmlElementGeneratorTools . generateValues ( columns , "item." , true ) ) { foreachEle . addElement ( element ) ; } insertEle . addElement ( new TextElement ( "on duplicate key update " ) ) ; // set Iterator < IntrospectedColumn > columnIterator = columns . iterator ( ) ; while ( columnIterator . hasNext ( ) ) { IntrospectedColumn column = columnIterator . next ( ) ; insertEle . addElement ( new TextElement ( MyBatis3FormattingUtilities . getEscapedColumnName ( column ) + " = values(" + MyBatis3FormattingUtilities . getEscapedColumnName ( column ) + ")" + ( columnIterator . hasNext ( ) ? "," : "" ) ) ) ; } document . getRootElement ( ) . addElement ( insertEle ) ; logger . debug ( "itfsw(存在即更新插件):" + introspecte T ble.getMyBatis3Xm l MapperFileName() + "增加" + (w i t B OBs ? "b t h UpsertWit B OBs" : "batchUpsert")  实现方法。"); }
批量
@param document
@param introspectedTable
@param withBLOBs
批量