[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
進行插件的生成