4

Like title, when i execute the mybatis-generator, i want to overwriting the already generated *Mapper.xml all, not merge! but i try many config way, it doesn't implement correct. and everytime is generator the more once the xml content. like this:

<resultMap id="BaseResultMap" type="com.test.entity.GoodsEntity"> ...
<resultMap id="BaseResultMap" type="com.test.entity.GoodsEntity"> ...
<resultMap id="BaseResultMap" type="com.test.entity.GoodsEntity"> ...

in the properties, i had add this line:

<mybatis.generator.overwrite>true</mybatis.generator.overwrite>

and in the build > plugin, i add below lines:

<plugin>
            <groupId>org.mybatis.generator</groupId>
            <artifactId>mybatis-generator-maven-plugin</artifactId>
            <version>1.3.5</version>
            <configuration>
                <verbose>true</verbose>
                <overwrite>true</overwrite>
                <configurationFile>${mybatis.generator.configurationFile}</configurationFile>
            </configuration>
            <executions>
                <execution>
                    <id>Generate MyBatis Artifacts</id>
                    <goals>
                        <goal>generate</goal>
                    </goals>
                </execution>
            </executions>
            <dependencies>
                <dependency>
                    <groupId>com.test</groupId>
                    <artifactId>ob-maven-plugin-mybatis-generator</artifactId>
                    <version>1.0</version>
                </dependency>
            </dependencies>
        </plugin>

in the mybatis-generator.xml, i try overwrite config yet. all config it doesn't work goo.

How could I modify the configuration?

kookob
  • 143
  • 1
  • 8

5 Answers5

1

MyBatis generator will always merge XML files if it finds a match. There is currently no option to turn that off.

Jeff Butler
  • 991
  • 6
  • 11
1

You can use plugin <plugin type="org.mybatis.generator.plugins.UnmergeableXmlMappersPlugin" /> in Mybatis Generator 1.3.7 to overwrite xml.

See http://www.mybatis.org/generator/reference/plugins.html

This plugin will disable the XML merge function for generated mapper XML files. This will cause the generator to respect the overwrite flag for XML files in the same way it does for Java files - if overwrite is true, then an existing file will be overwritten, else a new file will be written with a unique name.

This plugin can be helpful if you disable all comments.

Setting <property name="suppressAllComments" value="true" /> in Mybatis Generator configuration file can cause this problem. Mybatis Generator uses comments flag to decide whether to merge XML.

If you disable all comments, you might find the UnmergeableXmlMappersPlugin useful. It will cause the generator to respect the overwrite flag for XML files.

See http://www.mybatis.org/generator/configreference/commentGenerator.html

Community
  • 1
  • 1
xxg
  • 2,048
  • 1
  • 11
  • 14
0

I encountered the same problem today.To solve this problem, just need to change the version of mybatis-generator-maven-plugin。

<mybatis-generator-maven-plugin.version>1.3.4-SNAPSHOT</mybatis-generator-maven-plugin.version>
Chaucer
  • 51
  • 1
  • 1
0

I was able to get around this by creating a plugin and adding it to the mybatis-generator-config.xml file. Note, of course, that this solution will cause the Mapper.xml files to always be overwritten regardless of whether or not the -overwrite flag is specified.

mybatis-generator-config.xml:

<generatorConfiguration>
    ...
    <context id="myContextId">
        <plugin type="com.mydomain.DeleteExistingSqlMapsPlugin"></plugin>
        ...
    </context>
</generatorConfiguration>

DeleteExistingSqlMapsPlugin.java:

...
public class DeleteExistingSqlMapsPlugin extends PluginAdapter {

    @Override
    public boolean validate(List<String> warnings) {
        return true;
    }

    @Override
    public boolean sqlMapGenerated(GeneratedXmlFile sqlMap,
            IntrospectedTable introspectedTable)
    {
        String sqlMapPath = sqlMap.getTargetProject() + File.separator
                + sqlMap.getTargetPackage().replaceAll("\\.", File.separator)
                + File.separator + sqlMap.getFileName();
        File sqlMapFile = new File(sqlMapPath);

        sqlMapFile.delete();

        return true;
    }

}

This works because sqlMapGenerated() is called after a Mapper.xml file is created in memory but before it is written to disk.

D.L.
  • 314
  • 1
  • 7
  • Shouln't it be `sqlMap.getTargetPackage().replaceAll("\\.", Matcher.quoteReplacement(File.separator))` ? – 阿尔曼 Dec 26 '17 at 07:00
0

I write a plugin to merge xml mapper file.

And modifiy mybatis-generator-core to combine java and xml.

This can keep your xml and java file 's modification not override.

https://github.com/zwxbest/mybatis-generator-plugin

Usage:

<generatorConfiguration>
    ...
    <context id="myContextId">
        <plugin type="com.mydomain.CombineXmlPlugin"></plugin>
        ...
    </context>
</generatorConfiguration>

Plugin Code:

    package com.haitian.plugins;

import org.mybatis.generator.api.GeneratedXmlFile;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.PluginAdapter;
import org.mybatis.generator.api.ShellCallback;
import org.mybatis.generator.api.dom.xml.Element;
import org.mybatis.generator.internal.DefaultShellCallback;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.File;
import java.io.FileInputStream;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * User:zhangweixiao
 * Description:
 * old nodes is your existing xml file's first level nodes,like <insert><resultMap>
 *  new nodes is mybatis-generator generate for you to combine
 * This compare the first level node's name and "id" attribute of new nodes and old nodes
 * if the two equal,then new node will not generate
 * so this can make you modification in old nodes not override.
 * if you want to regenrate old node,delete it,it will generate new.
 */
public class CombineXmlPlugin extends PluginAdapter {
    //shellCallback use TargetProject and TargetPackage to get targetFile
    ShellCallback shellCallback = new DefaultShellCallback(false);
    //save new nodes
    org.mybatis.generator.api.dom.xml.Document document;

    @Override
    public boolean validate(List<String> warnings) {
        return true;
    }

    /**
     * assing document variable to get new nodes
     * @param document
     * @param introspectedTable
     * @return
     */
    @Override
    public boolean sqlMapDocumentGenerated(org.mybatis.generator.api.dom.xml.Document document,
                                           IntrospectedTable introspectedTable) {
        this.document = document;
        return true;
    }


    //new nodes is generated,but not write on disk,we just need to filter.
    @Override
    public boolean sqlMapGenerated(GeneratedXmlFile sqlMap,
                                   IntrospectedTable introspectedTable) {

        try {
            //get old nodes
            File directory = shellCallback.getDirectory(sqlMap.getTargetProject(), sqlMap.getTargetPackage());
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            dbf.setValidating(false);
            DocumentBuilder db = dbf.newDocumentBuilder();
            File xmlFile = new File(directory, sqlMap.getFileName());
            if (directory.exists() == false || xmlFile.exists() == false)
                return true;
            Document doc = db.parse(new FileInputStream(xmlFile));
            org.w3c.dom.Element rootElement = doc.getDocumentElement();
            NodeList list = rootElement.getChildNodes();
            //get new nodes
            List<Element> elements = document.getRootElement().getElements();

            //get nodeName and the value of id attribute use regex
            Pattern p = Pattern.compile("<(\\w+)\\s+id=\"(\\w+)\"");

            boolean findSameNode = false;
            // traverse new nodes to compare old nodes to filter
            for (Iterator<Element> elementIt = elements.iterator(); elementIt.hasNext(); ) {
                findSameNode = false;
                String newNodeName = "";
                String NewIdValue = "";
                Element element = elementIt.next();
                Matcher m = p.matcher(element.getFormattedContent(0));
                if (m.find()) {
                  //get nodeName and the value of id attribute
                    newNodeName = m.group(1);
                    NewIdValue = m.group(2);
                }
                //if the nodeName of newNode and oldNode are equal
                //and the id attribute of newNode and oldNode are equal
                //then filter newNode
                for (int i = 0; i < list.getLength(); i++) {
                    Node node = list.item(i);
                    if (node.getNodeType() == Node.ELEMENT_NODE) {
                        if (newNodeName.equals(node.getNodeName())) {
                            NamedNodeMap attr = node.getAttributes();
                            for (int j = 0; j < attr.getLength(); j++) {
                                Node attrNode = attr.item(j);
                                if (attrNode.getNodeName().equals("id") && attrNode.getNodeValue().equals(NewIdValue)) {
                                    //filter new node,just delete it ,and it will not generate
                                    elementIt.remove();
                                    findSameNode = true;
                                    break;
                                }
                            }
                            if (findSameNode == true)
                                break;
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return true;
    }
}

you add "batchInsert",and delte insertSelective,and modify other node. then regenerate xml mapper file,only insertSelective will be generated,others will not be override.

zwx
  • 569
  • 5
  • 7