mybatis generator工具在使用的时候的时候,命令行输入:-overwrite 参数,表示生成的文件会覆盖原来的文件;但是在实际使用中发现,针对mybatis生成的SQL映射文件(xml文件)只能追加,不能覆盖;对于实际的使用中,如果需要对通过该工具自动生成的代码进行重新生成,一般会选择全部文件覆盖的方式;而mybatis generator却没有覆盖的这个功能;
原因
在检查源码的时候发现 org.mybatis.generator.api.MyBatisGenerator中的generate 方法中,有对于xml文件是覆盖/追加的判断,源代码如下:
try {
File directory = shellCallback.getDirectory(gxf.getTargetProject(), gxf.getTargetPackage());
targetFile = new File(directory, gxf.getFileName());
if (targetFile.exists()) {
if (gxf.isMergeable()) {
source = XmlFileMergerJaxp.getMergedSource(gxf,targetFile);
} else if (shellCallback.isOverwriteEnabled()) {
source = gxf.getFormattedContent();
warnings.add(getString("Warning.11", targetFile.getAbsolutePath()));
} else {
source = gxf.getFormattedContent();
targetFile = getUniqueFileName(directory, gxf.getFileName());
warnings.add(getString("Warning.2", targetFile.getAbsolutePath()));
}
} else {
source = gxf.getFormattedContent();
}
} catch (ShellException e) {
warnings.add(e.getMessage());
continue;
}
通过其中的代码可知:先对gxf.isMergeable属性进行判断,是否合并(即追加),如果不合并的话,那么判断:shellCallback.isOverwriteEnabled() (这个属性是通过命令行的输入的 overwrite的参数控制的);
我们希望overwrite生效的话,必须让isMergeable判断为false,gxf 是一个 GeneratedXmlFile 的实例,是在:233行:
context.generateFiles(callback, generatedJavaFiles, generatedXmlFiles, warnings);
中生成的;通过Context的generateFiles方法中,是调用:generatedXmlFiles.addAll(introspectedTable.getGeneratedXmlFiles()); 来生成generatedXmlFiles ; 即针对mybatis3的IntrospectedTable 的实现类:IntrospectedTableMyBatis3Impl,其中的 getGeneratedXmlFiles的方法中,在构造GeneratedXmlFile类;查看该方法的代码如下:(仅:GeneratedXmlFile的构造方法)
GeneratedXmlFile gxf = new GeneratedXmlFile(document,
getMyBatis3XmlMapperFileName(), getMyBatis3XmlMapperPackage(),
context.getSqlMapGeneratorConfiguration().getTargetProject(),
true, context.getXmlFormatter());
对应GeneratedXmlFile 可知,倒数第二个参数即是 boolean isMergeable;原来在这里固定了传入:true ,导致了前端的overwrite无效;
处理方案
希望在不影响原来功能结构的情况下,增加对覆盖功能,即overwrite生效;决定对:IntrospectedTableMyBatis3Impl.getGeneratedXmlFiles方法进行改造,在生成:GeneratedXmlFile 对象的时候,对传入的isMergeable参数,进行控制;IntrospectedTableMyBatis3Impl中,有context的属性,决定对配置文件的Context 增加一个 mergeable 的属性;用于控制是否覆盖;由于重新生成的时候,覆盖的可能性更大,在默认没有设置该属性的时候,mergeable属性为:false,改造后的getGeneratedXmlFiles代码如下:
if (xmlMapperGenerator != null) {
Document document = xmlMapperGenerator.getDocument();
/**
* 原来中的 GeneratedXmlFile 保留;将其中构造函数中的true 修改为 : false;
* 设置 isMergeable = false; 在生成 xml文件的时候,将不是合并,而是直接覆盖;
*/
/*GeneratedXmlFile gxf = new GeneratedXmlFile(document,
getMyBatis3XmlMapperFileName(), getMyBatis3XmlMapperPackage(),
context.getSqlMapGeneratorConfiguration().getTargetProject(),
true, context.getXmlFormatter());*/
String tmp = context.getProperty("mergeable");
boolean mergeable = false;
if("true".equalsIgnoreCase(tmp)){
mergeable = true;
}
GeneratedXmlFile gxf = new GeneratedXmlFile(document,
getMyBatis3XmlMapperFileName(), getMyBatis3XmlMapperPackage(),
context.getSqlMapGeneratorConfiguration().getTargetProject(),
mergeable, context.getXmlFormatter());
if (context.getPlugins().sqlMapGenerated(gxf, this)) {
answer.add(gxf);
}
}
对generatorMybatis配置文件的Context标签下,可以增加属性标签,名称为:mergeable;例如:
该属性,仅在确实需要进行合并,而不是覆盖的情况下使用,且值要求为:true;没有该属性的时候,默认为false;