[TOC]
MyBatis Generator Plugin
Plugin用来在生成Java及XML的过程中修改或者添加内容。
其必须实现com.mybatis.generator.api.Plugin
接口。大多数插件应扩展适配器类org.mybatis.generator.api.PluginAdapter
。适配器类提供基本的插件支持,并为大多数的接口方法(类似于Swing适配器类)提供了空操作的方法。
插件的生命周期
- 插件通过默认的构造函数创建
- setContext方法被调用
- setProperties方法被调用
- validate方法被调用。如果该方法返回false ,那么插件中的其他方法都不会再被调用。
- 对于配置中的每个表:
- initialized方法被调用
- Java客户端的方法:
- clientXXXMethodGenerated(Method, TopLevelClass, IntrospectedTable) - 当Java客户端实现类生成的时候这些方法被调用.
- clientXXXMethodGenerated(Method, Interface, IntrospectedTable) -当Java客户端接口生成的时候这些方法被调用。
- clientGenerated(Interface, TopLevelClass, IntrospectedTable)方法被调用
- 模型方法:
- modelFieldGenerated, modelGetterMethodGenerated, modelSetterMethodGenerated for each field in the class
- modelExampleClassGenerated(TopLevelClass, IntrospectedTable)
- modelPrimaryKeyClassGenerated(TopLevelClass, IntrospectedTable)
- modelBaseRecordClassGenerated(TopLevelClass, IntrospectedTable)
- modelRecordWithBLOBsClassGenerated(TopLevelClass, IntrospectedTable)
- SQL映射方法:
- sqlMapXXXElementGenerated(XmlElement, IntrospectedTable) - 当生成SQL映射的每个元素的时候这些方法被调用
- sqlMapDocumentGenerated(Document, IntrospectedTable)
- sqlMapDocument(GeneratedXmlFile, IntrospectedTable)
- contextGenerateAdditionalJavaFiles(IntrospectedTable)方法被调用
- contextGenerateAdditionalXmlFiles(IntrospectedTable)方法被调用
- contextGenerateAdditionalJavaFiles()方法被调用
- contextGenerateAdditionalXmlFiles()方法被调用
可以在以下方法中生成自定义的xml或者Java文件:
contextGenerateAdditionalJavaFiles(IntrospectedTable)
contextGenerateAdditionalXmlFiles(IntrospectedTable)
contextGenerateAdditionalJavaFiles()
contextGenerateAdditionalXmlFiles()
如果生成的xml或者Java文件和当前的配置中的表相关,如需要根据每个表的xml及client生成新的自定义的xml或client,则使用带有参数的:
contextGenerateAdditionalJavaFiles(IntrospectedTable)
contextGenerateAdditionalXmlFiles(IntrospectedTable)
否则可以使用不带参数的:
contextGenerateAdditionalJavaFiles()
contextGenerateAdditionalXmlFiles()
如我们需要生成mybatis-config.xml配置文件,该文件和具体的表无关,则可以使用contextGenerateAdditionalXmlFiles()
.
可以参考muybatis-generator-core包里面plugin
目录下的SqlMapConfigPlugin
。
生成自定义Mapper及xml
如果我们把自己的业务写在默认的Mapper.java及Mapper.xml中时,如果业务很多,会发现代码很乱,如果想和默认的进行区分,
并且方便重新生成,则编写插件进行生成。
目的:
- 支持对生成的Mapper进行重命名,如需要把默认的Mapper生成为Dao
- 支持把默认的Mapper.java生成在mbg目录下,Mapper.xml生成在相应的mbg目录下
- 支持在custom目录生成新的Mappper.java及xml
其生成结构如:
src
├── main
│ ├── java
│ │ └── com
│ │ ├── demo
│ │ │ └── monitor
│ │ │ └── aly
│ │ │ ├── App.java
│ │ │ ├── config
│ │ │ │ └── AppConfig.java
│ │ │ ├── controller
│ │ │ │ └── IndexController.java
│ │ │ ├── dao
│ │ │ │ ├── custom
│ │ │ │ │ ├── EcsInfoMapper.java
│ │ │ │ │ └── SlbInfoMapper.java
│ │ │ │ └── mbg
│ │ │ │ ├── EcsInfoMBGMapper.java
│ │ │ │ └── SlbInfoMBGMapper.java
│ │ │ ├── model
│ │ │ │ ├── EcsInfo.java
│ │ │ │ └── SlbInfo.java
│ │ │ └── service
│ │ │ └── EcsInfoService.java
│ │ └── kkk
│ └── resources
│ ├── application.yml
│ ├── generatorConfig.xml
│ ├── log4j2.xml
│ ├── mapper
│ │ ├── custom
│ │ │ ├── EcsInfoMapper.xml
│ │ │ └── SlbInfoMapper.xml
│ │ └── mbg
│ │ ├── EcsInfoMBGMapper.xml
│ │ └── SlbInfoMBGMapper.xml
│ └── mybatis-config.xml
└── test
└── java
其代码如下:
import org.mybatis.generator.api.GeneratedJavaFile;
import org.mybatis.generator.api.GeneratedXmlFile;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.PluginAdapter;
import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;
import org.mybatis.generator.api.dom.java.Interface;
import org.mybatis.generator.api.dom.java.JavaVisibility;
import org.mybatis.generator.api.dom.xml.Attribute;
import org.mybatis.generator.api.dom.xml.Document;
import org.mybatis.generator.api.dom.xml.XmlElement;
import org.mybatis.generator.codegen.XmlConstants;
import org.mybatis.generator.internal.util.StringUtility;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RenamePlugin extends PluginAdapter {
private String searchStr;
private String replaceStr;
private Pattern pattern;
private boolean replaceFlag;
@Override
public boolean validate(List<String> list) {
searchStr = properties.getProperty("searchString");
replaceStr = properties.getProperty("replaceString");
boolean valid = StringUtility.stringHasValue(searchStr) && StringUtility.stringHasValue(replaceStr);
if (valid) {
pattern = Pattern.compile(searchStr);
replaceFlag = true;
} else {
searchStr = "";
replaceStr = "";
}
return true;
}
/**
* 重命名及更改默认的目录
* @param introspectedTable
*/
@Override
public void initialized(IntrospectedTable introspectedTable) {
//更改默认生成的Mapper.java为mbg目录下MBGMapper.java
String oldType = introspectedTable.getMyBatis3JavaMapperType();
if (replaceFlag) {
Matcher matcher = pattern.matcher(oldType);
oldType = matcher.replaceAll("MBG" + replaceStr);
} else {
oldType = oldType.replaceAll("Mapper", "MBGMapper");
}
int idx = oldType.lastIndexOf(".");
if (idx > 0) {
oldType = oldType.substring(0, idx) + ".mbg" + oldType.substring(idx);
}
introspectedTable.setMyBatis3JavaMapperType(oldType);
//更改默认生成的Mapper.java为mbg目录下MBGMapper.java
String mapperName = introspectedTable.getMyBatis3XmlMapperFileName();
if (replaceFlag) {
Matcher matcher = pattern.matcher(oldType);
mapperName = matcher.replaceAll("MBG" + replaceStr);
} else {
mapperName = mapperName.replaceAll("Mapper", "MBGMapper");
}
introspectedTable.setMyBatis3XmlMapperFileName(mapperName);
String mapperPkg = introspectedTable.getMyBatis3XmlMapperPackage() + File.separator + "mbg";
introspectedTable.setMyBatis3XmlMapperPackage(mapperPkg);
}
@Override
public List<GeneratedJavaFile> contextGenerateAdditionalJavaFiles(IntrospectedTable introspectedTable) {
List<GeneratedJavaFile> result = new ArrayList<>();
GeneratedJavaFile g = null;
for (GeneratedJavaFile f : introspectedTable.getGeneratedJavaFiles()) {
if (f.getFileName().contains("Dao") || f.getFileName().contains("Mapper")) {
g = f;
break;
}
}
if (g != null) {
String pkgName = g.getTargetPackage().replace("mbg", "custom");
String className = g.getCompilationUnit().getType().getShortName().replace("MBG", "");
Interface customInterface = new Interface(pkgName + "." + className);
customInterface.setVisibility(JavaVisibility.PUBLIC);
FullyQualifiedJavaType daoType = new FullyQualifiedJavaType(g.getCompilationUnit().getType().getFullyQualifiedName());
customInterface.addSuperInterface(daoType);
customInterface.addImportedType(daoType);
String target = g.getTargetProject();
String fileName = (target + File.separator + pkgName + "." + className).replace(".", File.separator);
File file = new File(fileName + ".java");
if (!file.exists()) {
GeneratedJavaFile tmp = new GeneratedJavaFile(customInterface, target, context.getJavaFormatter());
result.add(tmp);
}
}
return result;
}
/**
* 为相应的默认的xml文件生成一个自定义的xml,自己实现的可以都写在该文件中
* @param introspectedTable
* @return
*/
@Override
public List<GeneratedXmlFile> contextGenerateAdditionalXmlFiles(IntrospectedTable introspectedTable) {
List<GeneratedXmlFile> result = new ArrayList<>();
GeneratedXmlFile mbgXml = introspectedTable.getGeneratedXmlFiles().get(0);
String projectName = mbgXml.getTargetProject();
String packageName = mbgXml.getTargetPackage().replace("mbg", "custom");
GeneratedJavaFile g = null;
for (GeneratedJavaFile f : introspectedTable.getGeneratedJavaFiles()) {
if (f.getFileName().contains("Dao") || f.getFileName().contains("Mapper")) {
g = f;
break;
}
}
if (g != null) {
Document document = new Document(XmlConstants.MYBATIS3_MAPPER_CONFIG_PUBLIC_ID,
XmlConstants.MYBATIS3_MAPPER_SYSTEM_ID);
XmlElement root = new XmlElement("mapper");
String className = g.getFileName().replace("MBG", "");
String fileName = g.getFileName().replace("MBG", "").replace(".java", ".xml");
String pkgName = g.getTargetPackage().replace(".mbg", ".custom");
Attribute attribute = new Attribute("namespace", pkgName + "." + className.replace(".java", ""));
root.addAttribute(attribute);
document.setRootElement(root);
File file = new File(projectName + File.separator + packageName + File.separator + fileName);
if (!file.exists()) {
GeneratedXmlFile gxf = new GeneratedXmlFile(document, fileName, packageName,
projectName, false, context.getXmlFormatter());
result.add(gxf);
}
}
return result;
}
}
自定义插件
功能:美化model的生成样式,其中属性注释为:列名 : 列注释
package com.liukun.mgenerator;
import org.mybatis.generator.api.IntrospectedColumn;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.PluginAdapter;
import org.mybatis.generator.api.dom.java.Field;
import org.mybatis.generator.api.dom.java.Interface;
import org.mybatis.generator.api.dom.java.Method;
import org.mybatis.generator.api.dom.java.TopLevelClass;
import java.util.List;
/**
* Created by HFJY on 2017/6/30.
*/
public class Demo extends PluginAdapter {
private void print(Throwable throwable) {
System.out.println(throwable.getStackTrace()[0].getMethodName());
}
@Override
public boolean validate(List<String> list) {
return true;
}
@Override
public boolean clientDeleteByPrimaryKeyMethodGenerated(Method method, Interface interfaze, IntrospectedTable introspectedTable) {
method.getJavaDocLines().set(1," * clientDeleteByPrimaryKeyMethodGenerated!测试");
method.getJavaDocLines().remove(2);
return super.clientDeleteByPrimaryKeyMethodGenerated(method, interfaze, introspectedTable);
}
@Override
public boolean modelFieldGenerated(Field field, TopLevelClass topLevelClass, IntrospectedColumn introspectedColumn, IntrospectedTable introspectedTable, ModelClassType modelClassType) {
field.getJavaDocLines().set(1," * " + introspectedColumn.getActualColumnName() + " : " + introspectedColumn.getRemarks());
field.getJavaDocLines().remove(2);
field.getJavaDocLines().remove(2);
return super.modelFieldGenerated(field, topLevelClass, introspectedColumn, introspectedTable, modelClassType);
}
@Override
public boolean modelGetterMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedColumn introspectedColumn, IntrospectedTable introspectedTable, ModelClassType modelClassType) {
method.getJavaDocLines().remove(1);
method.getJavaDocLines().remove(1);
return super.modelGetterMethodGenerated(method, topLevelClass, introspectedColumn, introspectedTable, modelClassType);
}
@Override
public boolean modelSetterMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedColumn introspectedColumn, IntrospectedTable introspectedTable, ModelClassType modelClassType) {
method.getJavaDocLines().remove(1);
method.getJavaDocLines().remove(1);
return super.modelSetterMethodGenerated(method, topLevelClass, introspectedColumn, introspectedTable, modelClassType);
}
}
项目进行打包,其它项目在maven中引用该插件
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.5</version>
<configuration>
<overwrite>true</overwrite>
</configuration>
<dependencies>
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.3.5</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
</dependency>
<dependency>
<groupId>com.liukun.mybatis.generator</groupId>
<artifactId>demogenerator</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</plugin>
并且在resources/generatorConfig.xml
中相应的context
下引入该插件即可:
<plugin type="com.liukun.mgenerator.Demo"></plugin>
这时就可以通过mvn mybatis-generator:generate
进行插件的生成