用 IEDA 的 New Project 创建一个新的空的 Maven 类型的项目 JDK 选择 11
下面是添加依赖和相关设置的完整的 pom.xml (在Mac OS下)
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.longser.mybatis</groupId>
<artifactId>generatorr</artifactId>
<version>1.0</version>
<properties>
<java.version>1.11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.4.0</version>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>11</source>
<target>11</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<version>3.0.0-M1</version>
</plugin>
</plugins>
</pluginManagement>
</build>
<distributionManagement>
<repository>
<id>localRepository</id>
<url>file:~/.m2/Repository</url>
</repository>
</distributionManagement>
</project>
下面是注释生成器和插件的代码
package com.longser.mybatis.generator;
import static org.mybatis.generator.internal.util.StringUtility.isTrue;
import java.text.SimpleDateFormat;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.Properties;
import java.util.Set;
import org.mybatis.generator.api.CommentGenerator;
import org.mybatis.generator.api.IntrospectedColumn;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.api.dom.java.CompilationUnit;
import org.mybatis.generator.api.dom.java.Field;
import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;
import org.mybatis.generator.api.dom.java.InnerClass;
import org.mybatis.generator.api.dom.java.InnerEnum;
import org.mybatis.generator.api.dom.java.JavaElement;
import org.mybatis.generator.api.dom.java.Method;
import org.mybatis.generator.api.dom.java.Parameter;
import org.mybatis.generator.api.dom.java.TopLevelClass;
import org.mybatis.generator.api.dom.kotlin.KotlinFile;
import org.mybatis.generator.api.dom.xml.TextElement;
import org.mybatis.generator.api.dom.xml.XmlElement;
import org.mybatis.generator.config.MergeConstants;
import org.mybatis.generator.config.PropertyRegistry;
import org.mybatis.generator.internal.util.StringUtility;
/**
*
* <p>自定义的MyBatis Generator注释生成器</p>
* <p>内容是在官方代码基础上修改的</p>
*
* @see org.mybatis.generator.api.CommentGenerator
* @see org.mybatis.generator.internal.DefaultCommentGenerator
* @see "https://github.com/mybatis/generator/blob/master/core/mybatis-generator-core/src/main/java/org/mybatis/generator/internal/DefaultCommentGenerator.java"
*
* @author David
* @version 1.0.0
* @since 2021年6月11日
*/
@SuppressWarnings("unused")
public class MyCommentGenerator implements CommentGenerator {
private final Properties properties;
/**
* 抑制日期 默认false:不抑制
*/
private boolean suppressDate;
/**
* 抑制注释 默认false:不抑制
*/
private boolean suppressAllComments;
/**
* 显示数据库comments 默认false:不显示
* 如果suppressAllComments是true, 这个选项被忽略
*/
private boolean addRemarkComments;
/**
* 日期格式
*/
private SimpleDateFormat dateFormat;
/**
* 当前用户的名字
*/
private final String userName;
public MyCommentGenerator() {
super();
properties = new Properties();
suppressDate = false;
suppressAllComments = false;
addRemarkComments = false;
userName = System.getProperty("user.name");
}
@Override
public void addJavaFileComment(CompilationUnit compilationUnit) {
// add no file level comments by default
}
/**
* @param xmlElement the xml element
*/
@Override
public void addComment(XmlElement xmlElement) {
if (suppressAllComments) {
return;
}
xmlElement.addElement(new TextElement("<!-- " + MergeConstants.NEW_ELEMENT_TAG + " -->"));
}
@Override
public void addRootComment(XmlElement rootElement) {
// add no document level comments by default
}
/**
* 读取配置文件
*/
@Override
public void addConfigurationProperties(Properties properties) {
this.properties.putAll(properties);
suppressDate = isTrue(properties.getProperty(PropertyRegistry.COMMENT_GENERATOR_SUPPRESS_DATE));
suppressAllComments = isTrue(properties.getProperty(PropertyRegistry.COMMENT_GENERATOR_SUPPRESS_ALL_COMMENTS));
addRemarkComments = isTrue(properties.getProperty(PropertyRegistry.COMMENT_GENERATOR_ADD_REMARK_COMMENTS));
String dateFormatString = properties.getProperty(PropertyRegistry.COMMENT_GENERATOR_DATE_FORMAT);
if (StringUtility.stringHasValue(dateFormatString)) {
dateFormat = new SimpleDateFormat(dateFormatString);
}
}
/**
* This method adds the custom javadoc tag for. You may do nothing if you do not
* wish to include the Javadoc tag - however, if you do not include the Javadoc
* tag then the Java merge capability of the eclipse plugin will break.
*
* @param javaElement the java element
* @param markAsDoNotDelete the mark as do not delete
*/
protected void addJavadocTag(JavaElement javaElement, boolean markAsDoNotDelete) {
javaElement.addJavaDocLine(" *");
String sb = " * " +
MergeConstants.NEW_ELEMENT_TAG;
javaElement.addJavaDocLine(sb);
}
/**
* Returns a formated date string to include in the Javadoc tag and XML
* comments. You may return null if you do not want the date in these
* documentation elements.
*
* @return a string representing the current timestamp, or null
*/
protected String getDateString() {
if (suppressDate) {
return null;
} else if (dateFormat != null) {
return dateFormat.format(new Date());
} else {
return new Date().toString();
}
}
@Override
public void addClassComment(InnerClass innerClass, IntrospectedTable introspectedTable) {
if (suppressAllComments) {
return;
}
innerClass.addJavaDocLine("/**");
innerClass.addJavaDocLine(" * ");
String remarks = introspectedTable.getRemarks();
if (addRemarkComments && StringUtility.stringHasValue(remarks)) {
String[] remarkLines = remarks.split(System.getProperty("line.separator"));
for (String remarkLine : remarkLines) {
innerClass.addJavaDocLine(" * <p>" + remarkLine);
}
}
innerClass.addJavaDocLine(" * ");
innerClass.addJavaDocLine(" * @author " + userName);
innerClass.addJavaDocLine(" * @date " + getDateString());
innerClass.addJavaDocLine(" */");
}
@Override
public void addClassComment(InnerClass innerClass, IntrospectedTable introspectedTable, boolean markAsDoNotDelete) {
addClassComment(innerClass, introspectedTable);
}
/**
* 创建的数据表对应的类添加的注释
*/
@Override
public void addModelClassComment(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
if (suppressAllComments) {
return;
}
topLevelClass.addJavaDocLine("/**");
topLevelClass.addJavaDocLine(" * ");
String remarks = introspectedTable.getRemarks();
if (addRemarkComments && StringUtility.stringHasValue(remarks)) {
String[] remarkLines = remarks.split(System.getProperty("line.separator"));
for (String remarkLine : remarkLines) {
topLevelClass.addJavaDocLine(" * " + remarkLine);
}
}
topLevelClass.addJavaDocLine(" * ");
topLevelClass.addJavaDocLine(" * @author " + userName);
topLevelClass.addJavaDocLine(" * @version 1.0");
topLevelClass.addJavaDocLine(" * @since " + getDateString());
topLevelClass.addJavaDocLine(" * ");
topLevelClass.addJavaDocLine(" * Copyright by Longser Technologies Ltd. ");
topLevelClass.addJavaDocLine(" */");
}
@Override
public void addEnumComment(InnerEnum innerEnum, IntrospectedTable introspectedTable) {
if (suppressAllComments) {
return;
}
innerEnum.addJavaDocLine("/**");
innerEnum.addJavaDocLine(" * ");
String remarks = introspectedTable.getRemarks();
if (addRemarkComments && StringUtility.stringHasValue(remarks)) {
String[] remarkLines = remarks.split(System.getProperty("line.separator"));
for (String remarkLine : remarkLines) {
innerEnum.addJavaDocLine(" * " + remarkLine);
}
}
innerEnum.addJavaDocLine(" * @author " + userName);
innerEnum.addJavaDocLine(" * @date " + getDateString());
innerEnum.addJavaDocLine(" */");
}
/**
* <p>生成xx.java文件(model)属性的注释</p>
*/
@Override
public void addFieldComment(Field field, IntrospectedTable introspectedTable,
IntrospectedColumn introspectedColumn) {
if (suppressAllComments) {
return;
}
field.addJavaDocLine("/**");
// 获取列注释并加入到注解中
String remarks = introspectedColumn.getRemarks();
if (addRemarkComments && StringUtility.stringHasValue(remarks)) {
String[] remarkLines = remarks.split(System.getProperty("line.separator"));
for (String remarkLine : remarkLines) {
field.addJavaDocLine(" * " + remarkLine);
}
}
field.addJavaDocLine(" */");
}
@Override
public void addFieldComment(Field field, IntrospectedTable introspectedTable) {
}
/**
* xxxMapper接口和xxxExample类方法注解
*/
@Override
public void addGeneralMethodComment(Method method, IntrospectedTable introspectedTable) {
if (suppressAllComments) {
return;
}
method.addJavaDocLine("/**");
List<Parameter> parameters = method.getParameters();
for(Parameter parameter : parameters) {
String sb = " * @param " +
parameter.getName();
method.addJavaDocLine(sb);
}
Optional<FullyQualifiedJavaType> returnType = method.getReturnType();
returnType.ifPresent(x -> method.addJavaDocLine(" * @return " + x.getShortName()));
method.addJavaDocLine(" */");
}
@Override
public void addGetterComment(Method method, IntrospectedTable introspectedTable,
IntrospectedColumn introspectedColumn) {
}
@Override
public void addSetterComment(Method method, IntrospectedTable introspectedTable,
IntrospectedColumn introspectedColumn) {
}
@Override
public void addGeneralMethodAnnotation(Method method, IntrospectedTable introspectedTable,
Set<FullyQualifiedJavaType> imports) {
addGeneralMethodComment(method, introspectedTable);
}
@Override
public void addGeneralMethodAnnotation(Method method, IntrospectedTable introspectedTable,
IntrospectedColumn introspectedColumn, Set<FullyQualifiedJavaType> imports) {
addGeneralMethodComment(method, introspectedTable);
}
@Override
public void addFieldAnnotation(Field field, IntrospectedTable introspectedTable,
Set<FullyQualifiedJavaType> imports) {
addFieldComment(field, introspectedTable);
}
@Override
public void addFieldAnnotation(Field field, IntrospectedTable introspectedTable,
IntrospectedColumn introspectedColumn, Set<FullyQualifiedJavaType> imports) {
addFieldComment(field, introspectedTable, introspectedColumn);
}
@Override
public void addClassAnnotation(InnerClass innerClass, IntrospectedTable introspectedTable,
Set<FullyQualifiedJavaType> imports) {
}
@SuppressWarnings("unused")
private String getGeneratedAnnotation(String comment) {
StringBuilder buffer = new StringBuilder();
buffer.append("@Generated(");
if (suppressAllComments) {
buffer.append('\"');
} else {
buffer.append("value=\"");
}
buffer.append(MyBatisGenerator.class.getName());
buffer.append('\"');
if (!suppressDate && !suppressAllComments) {
buffer.append(", date=\"");
buffer.append(DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(ZonedDateTime.now()));
buffer.append('\"');
}
if (!suppressAllComments) {
buffer.append(", comments=\"");
buffer.append(comment);
buffer.append('\"');
}
buffer.append(')');
return buffer.toString();
}
@Override
public void addFileComment(KotlinFile kotlinFile) {
}
}
package com.longser.mybatis.generator.plugins;
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.FullyQualifiedJavaType;
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 org.mybatis.generator.config.PropertyRegistry;
import org.mybatis.generator.internal.util.StringUtility;
import java.text.SimpleDateFormat;
import java.util.*;
import static org.mybatis.generator.internal.util.StringUtility.isTrue;
/**
* @author Sin
* @date 2019/04/04/11:15
*/
@SuppressWarnings("unused")
public class LombokPlugin extends PluginAdapter {
private final Collection<Annotations> annotations;
/**
* 抑制日期 默认false:不抑制
*/
private final boolean suppressDate;
/**
* 抑制注释 默认false:不抑制
*/
private final boolean suppressAllComments;
/**
* 日期格式
*/
private SimpleDateFormat dateFormat;
/**
* 当前用户的名字
*/
private final String userName;
/**
* LombokPlugin constructor
*/
public LombokPlugin() {
super();
annotations = new LinkedHashSet<>(Annotations.values().length);
Properties properties = new Properties();
suppressDate = isTrue(properties.getProperty(PropertyRegistry.COMMENT_GENERATOR_SUPPRESS_DATE));
suppressAllComments = isTrue(properties.getProperty(PropertyRegistry.COMMENT_GENERATOR_SUPPRESS_ALL_COMMENTS));
String dateFormatString = properties.getProperty(PropertyRegistry.COMMENT_GENERATOR_DATE_FORMAT);
if (StringUtility.stringHasValue(dateFormatString)) {
dateFormat = new SimpleDateFormat(dateFormatString);
}
userName = System.getProperty("user.name");
}
/**
* Returns a formated date string to include in the Javadoc tag and XML
* comments. You may return null if you do not want the date in these
* documentation elements.
*
* @return a string representing the current timestamp, or null
*/
protected String getDateString() {
if (suppressDate) {
return null;
} else if (dateFormat != null) {
return dateFormat.format(new Date());
} else {
return new Date().toString();
}
}
/**
* @param list warnings list of warnings
* @return always true
*/
@Override
public boolean validate(List<String> list) {
return true;
}
/**
* Intercepts base record class generation
*
* @param topLevelClass the generated base record class
* @param introspectedTable The class containing information about the table as
* introspected from the database
* @return always true
*/
@Override
public boolean modelBaseRecordClassGenerated(
TopLevelClass topLevelClass,
IntrospectedTable introspectedTable
) {
addAnnotations(topLevelClass);
//实体类的import
//topLevelClass.addImportedType("java.io.Serializable");
//接口
//topLevelClass.addSuperInterface(new FullyQualifiedJavaType("java.io.Serializable"));
return true;
}
/**
* Intercepts primary key class generation
*
* @param topLevelClass the generated primary key class
* @param introspectedTable The class containing information about the table as
* introspected from the database
* @return always true
*/
@Override
public boolean modelPrimaryKeyClassGenerated(
TopLevelClass topLevelClass,
IntrospectedTable introspectedTable
) {
addAnnotations(topLevelClass);
return true;
}
/**
* Intercepts "record with blob" class generation
*
* @param topLevelClass the generated record with BLOBs class
* @param introspectedTable The class containing information about the table as
* introspected from the database
* @return always true
*/
@Override
public boolean modelRecordWithBLOBsClassGenerated(
TopLevelClass topLevelClass,
IntrospectedTable introspectedTable
) {
addAnnotations(topLevelClass);
return true;
}
@Override
public void setProperties(Properties properties) {
super.setProperties(properties);
//@Data is default annotation
annotations.add(Annotations.DATA);
for (String annotationName : properties.stringPropertyNames()) {
if (annotationName.contains(".")) {
// Not an annotation name
continue;
}
String value = properties.getProperty(annotationName);
if (!Boolean.parseBoolean(value)) {
// The annotation is disabled, skip it
continue;
}
Annotations annotation = Annotations.getValueOf(annotationName);
if (annotation == null) {
continue;
}
String optionsPrefix = annotationName + ".";
for (String propertyName : properties.stringPropertyNames()) {
if (!propertyName.startsWith(optionsPrefix)) {
// A property not related to this annotation
continue;
}
String propertyValue = properties.getProperty(propertyName);
annotation.appendOptions(propertyName, propertyValue);
}
annotations.add(annotation);
annotations.addAll(Annotations.getDependencies(annotation));
}
}
@Override
public boolean clientGenerated(Interface interfaze, IntrospectedTable introspectedTable) {
//Mapper文件的注释
if(!suppressAllComments) {
interfaze.addJavaDocLine("/**");
interfaze.addJavaDocLine(" * ");
String remarks = introspectedTable.getRemarks();
if (StringUtility.stringHasValue(remarks)) {
String[] remarkLines = remarks.split(System.getProperty("line.separator"));
for (String remarkLine : remarkLines) {
interfaze.addJavaDocLine(" * " + remarkLine + " 映射定义");
}
}
interfaze.addJavaDocLine(" * ");
interfaze.addJavaDocLine(" * @author " + userName);
interfaze.addJavaDocLine(" * @version 1.0");
interfaze.addJavaDocLine(" * @since " + getDateString());
interfaze.addJavaDocLine(" * ");
interfaze.addJavaDocLine(" * Copyright by Longser Technologies Ltd. ");
interfaze.addJavaDocLine(" */");
}
return true;
}
@Override
public boolean modelSetterMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedColumn introspectedColumn, IntrospectedTable introspectedTable, ModelClassType modelClassType) {
//不生成getter
return false;
}
@Override
public boolean modelGetterMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedColumn introspectedColumn, IntrospectedTable introspectedTable, ModelClassType modelClassType) {
//不生成setter
return false;
}
/**
* Adds the lombok annotations' imports and annotations to the class
*
* @param topLevelClass the partially implemented model class
*/
private void addAnnotations(TopLevelClass topLevelClass) {
for (Annotations annotation : annotations) {
topLevelClass.addImportedType(annotation.javaType);
topLevelClass.addAnnotation(annotation.asAnnotation());
}
}
private enum Annotations {
DATA("data", "@Data", "lombok.Data"),
BUILDER("builder", "@Builder", "lombok.Builder"),
ALL_ARGS_CONSTRUCTOR("allArgsConstructor", "@AllArgsConstructor", "lombok.AllArgsConstructor"),
NO_ARGS_CONSTRUCTOR("noArgsConstructor", "@NoArgsConstructor", "lombok.NoArgsConstructor"),
ACCESSORS("accessors", "@Accessors", "lombok.experimental.Accessors"),
TO_STRING("toString", "@ToString", "lombok.ToString");
private final String paramName;
private final String name;
private final FullyQualifiedJavaType javaType;
private final List<String> options;
Annotations(String paramName, String name, String className) {
this.paramName = paramName;
this.name = name;
this.javaType = new FullyQualifiedJavaType(className);
this.options = new ArrayList<>();
}
private static Annotations getValueOf(String paramName) {
for (Annotations annotation : Annotations.values()) {
if (String.CASE_INSENSITIVE_ORDER.compare(paramName, annotation.paramName) == 0) {
return annotation;
}
}
return null;
}
private static Collection<Annotations> getDependencies(Annotations annotation) {
if (annotation == ALL_ARGS_CONSTRUCTOR) {
return Collections.singleton(NO_ARGS_CONSTRUCTOR);
} else {
return Collections.emptyList();
}
}
// A trivial quoting.
// Because Lombok annotation options type is almost String or boolean.
private static String quote(String value) {
if (Boolean.TRUE.toString().equals(value) || Boolean.FALSE.toString().equals(value)) {
// case of boolean, not passed as an array.
return value;
}
return value.replaceAll("[\\w]+", "\"$0\"");
}
private void appendOptions(String key, String value) {
String keyPart = key.substring(key.indexOf(".") + 1);
String valuePart = value.contains(",") ? String.format("{%s}", value) : value;
this.options.add(String.format("%s=%s", keyPart, quote(valuePart)));
}
private String asAnnotation() {
if (options.isEmpty()) {
return name;
}
StringBuilder sb = new StringBuilder();
sb.append(name);
sb.append("(");
boolean first = true;
for (String option : options) {
if (first) {
first = false;
} else {
sb.append(", ");
}
sb.append(option);
}
sb.append(")");
return sb.toString();
}
}
}
执行 Maven 项目的 package 和 deploy,就可以在你本地的依赖库中部署好生成器的 jar 文件
下面是在Mac OS 系统中部署后的情况