mybatis代码生成+自定义注解+自定义注释 - 紫月java - 博客园

TOC

mybatis代码生成

<!--mybatis的包和反向生成的包__用来生成dao,entity层-->

    <!\-\- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.4.4</version>
    </dependency>
    <!\-\- mybatis-generator-core 反向生成java代码-->
    <dependency>
        <groupId>org.mybatis.generator</groupId>
        <artifactId>mybatis-generator-core</artifactId>
        <version>1.3.5</version>
    </dependency>

配置文件

resources文件夹中创建文件mbgConfiguration.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration

    PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
    "http://mybatis.org/dtd/mybatis-generator-config\_1\_0.dtd">

<!-- 第一种mybatis逆向生成xml配置 -->
<generatorConfiguration>

<context id="sqlserverTables" targetRuntime="MyBatis3" defaultModelType="flat">
    <!\-\- 自动识别数据库关键字,默认false,如果设置为true,根据SqlReservedWords中定义的关键字列表;
        一般保留默认值,遇到数据库关键字(Java关键字),使用columnOverride覆盖
     -->
    <!--<property name="autoDelimitKeywords" value="false"/>-->
    <!\-\- 生成的Java文件的编码 -->
    <property name="javaFileEncoding" value="UTF-8"/>
    <!\-\- 格式化java代码 -->
    <property name="javaFormatter" value="org.mybatis.generator.api.dom.DefaultJavaFormatter"/>
    <!\-\- 格式化XML代码 -->
    <property name="xmlFormatter" value="org.mybatis.generator.api.dom.DefaultXmlFormatter"/>
    <!\-\- beginningDelimiter和endingDelimiter:指明数据库的用于标记数据库对象名的符号,比如ORACLE就是双引号,MYSQL默认是`反引号; -->
    <property name="beginningDelimiter" value="`"/>
    <property name="endingDelimiter" value="`"/>
    <!\-\- 使用自定义的插件:entity的lombok注解 -->
    <plugin type="net.cc.gen.utils.LombokPlugin"/>
    <!--todo 文件名替换-->
    <!\-\- 此处是将Example改名为Criteria 当然 想改成什么都行~    -->
    <plugin type="org.mybatis.generator.plugins.RenameExampleClassPlugin">
        <property name="searchString" value="Example$" />
        <!\-\- 替换后 <property name="replaceString" value="Criteria" /> -->
        <property name="replaceString" value="Query" />
    </plugin>
    <!\-\- 此处是将UserMapper.xml改名为UserDao.xml 当然 想改成什么都行~ -->
    <!--<plugin type="org.mybatis.generator.plugins.rename.RenameSqlMapperPlugin">-->
        <!--<property name="searchString" value="Mapper" />-->
        <!--<property name="replaceString" value="Dao" />-->
    <!--</plugin>-->
    <!\-\- 此处是将UserMapper改名为UserDao 接口 当然 想改成什么都行~  -->
    <!--<plugin type="org.mybatis.generator.plugins.rename.RenameJavaMapperPlugin">-->
        <!--<property name="searchString" value="Mapper$" />-->
        <!--<property name="replaceString" value="Dao" />-->
    <!--</plugin>-->
    <!\-\-  通过type指定自定义的注释 -->
    <commentGenerator type="net.cc.gen.utils.MyCommentGenerator"/>
    <!--todo 数据库链接URL、用户名、密码 -->
    <jdbcConnection driverClass="com.mysql.jdbc.Driver"
                    connectionURL="jdbc:mysql://localhost:3306/project1?useUnicode=true&amp;useSSL=false&amp;characterEncoding=utf8"
                    userId="test"
                    password="123456"/>
    <javaTypeResolver>
        <property name="forceBigDecimals" value="false"/>
    </javaTypeResolver>
    <!--todo entity包路径-->
    <javaModelGenerator targetPackage="com.cc.learn.entity" targetProject="src/main/java">
        <!\-\- 在targetPackage的基础上,根据数据库的schema再生成一层package,最终生成的类放在这个package下,默认为false -->
        <property name="enableSubPackages" value="true"/>
        <!\-\- 从数据库返回的值被清理前后的空格,对String类型字段调用trim()方法  -->
        <property name="trimStrings" value="true"/>
    </javaModelGenerator>
    <!--todo mapper的xml路径-->
    <sqlMapGenerator targetPackage="mappings" targetProject="src/main/resources">
        <property name="enableSubPackages" value="true"/>
    </sqlMapGenerator>
    <!--todo mapper的java文件路径-->
    <javaClientGenerator type="XMLMAPPER" targetPackage="com.cc.learn.dao.mysql.mapper"
                         targetProject="src/main/java">
        <property name="enableSubPackages" value="true"/>
    </javaClientGenerator>
    <!--todo tableName需要生成的table名字
     useActualColumnNames 驼峰命名
     字段类型为text格式的字段需要专门配置
       <columnOverride column="AIRSPACE_DATA" javaType="java.lang.String" jdbcType="VARCHAR"/>
        <columnOverride column="AIRSPACES_DESC" javaType="java.lang.String" jdbcType="VARCHAR"/>
    -->
    <table tableName="User" schema="crmii" delimitIdentifiers="true"><property name="useActualColumnNames" value="false"/></table>
    <!--<table tableName="数据表2" schema="crmii" delimitIdentifiers="true"><property name="useActualColumnNames" value="false"/></table>-->
    <!--<table tableName="数据表3" schema="crmii" delimitIdentifiers="true"><property name="useActualColumnNames" value="false"/></table>-->
</context>

</generatorConfiguration>

配置类

自定义的lombok注解配置

效果:

在类上添加注解

@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class User {
}

在时间字段上自动添加注解

@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date endTime;

代码

import org.mybatis.generator.api.IntrospectedColumn;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.Plugin;
import org.mybatis.generator.api.PluginAdapter;
import org.mybatis.generator.api.dom.java.*;
import java.util.*;
/** 自定义的lombok注解配置
* @author jingshiyu
* @date 2019/9/17 12:04:47
* @desc
*/
public class LombokPlugin extends PluginAdapter {

private final Collection<Annotations> annotations;
/**
 \* LombokPlugin constructor
 */
public LombokPlugin() {
    annotations = new LinkedHashSet<>(Annotations.values().length);
}
/**
 \* @param warnings list of warnings
 \* @return always true
 */
@Override
public boolean validate(List<String\> warnings) {
    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);
    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;
}
/**
 \* 设置get set方法(使用lombok不需要,直接返回false)
 */
@Override
public boolean modelGetterMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedColumn introspectedColumn, IntrospectedTable introspectedTable, ModelClassType modelClassType) {
    return false;
}
/**
 \* 设置set方法
 */
@Override
public boolean modelSetterMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedColumn introspectedColumn, IntrospectedTable introspectedTable, ModelClassType modelClassType) {
    return false;
}
/**
 \* 设置lombok注解 <br>
 */
private void addAnnotations(TopLevelClass topLevelClass) {
    for (Annotations annotation : annotations) {
        topLevelClass.addImportedType(annotation.javaType);
        topLevelClass.addAnnotation(annotation.asAnnotation());
    }
}
/**
 \* entity类设置
 \* @param properties
 */
@Override
public void setProperties(Properties properties) {
    super.setProperties(properties);
    //@Data is default annotation
    annotations.add(Annotations.DATA);
    annotations.add(Annotations.ALL\_ARGS\_CONSTRUCTOR);
    annotations.add(Annotations.NO\_ARGS\_CONSTRUCTOR);
    annotations.add(Annotations.BUILDER);
    for (String annotationName : properties.stringPropertyNames()) {
        if (annotationName.contains(".")) {
            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));
        }
    }
}
/**
 \* mapper类设置注解
 */
@Override
public boolean clientGenerated(Interface interfaze, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
    interfaze.addImportedType(new FullyQualifiedJavaType("org.apache.ibatis.annotations.Mapper"));
    interfaze.addAnnotation("@Mapper");
    return true;
}
/**
 \* entity字段设置
 */
@Override
public boolean modelFieldGenerated(Field field, TopLevelClass topLevelClass, IntrospectedColumn introspectedColumn, IntrospectedTable introspectedTable, Plugin.ModelClassType modelClassType) {
    if (field.getType().getShortNameWithoutTypeArguments().equals("Date")) {
        field.getAnnotations().add(Annotations.DATE\_TIME\_FORMAT.asAnnotation());
        field.getAnnotations().add(Annotations.JSON_FORMAT.asAnnotation());
        topLevelClass.addImportedType(Annotations.DATE\_TIME\_FORMAT.javaType);
        topLevelClass.addImportedType(Annotations.JSON_FORMAT.javaType);
    }
    return true;
}
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"),
    DATE\_TIME\_FORMAT("dateTimeFormat", "@DateTimeFormat(pattern = \\"yyyy-MM-dd HH:mm:ss\\")", "org.springframework.format.annotation.DateTimeFormat"),
    JSON_FORMAT("jsonFormat", "@JsonFormat(pattern = \\"yyyy-MM-dd HH:mm:ss\\")", "com.fasterxml.jackson.annotation.JsonFormat");
    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<String>();
    }
    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();
    }
}

}

代码注释配置

代码生成时,使用数据控的注释给字段添加文档注释

效果

/**

 \* 编号
 */
private String planId;

代码

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import org.mybatis.generator.api.CommentGenerator;
import org.mybatis.generator.api.IntrospectedColumn;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.dom.java.*;
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;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Properties;
import static org.mybatis.generator.internal.util.StringUtility.isTrue;
/**
* mybatis逆向工程默认的注释修改(使用表的注释)
*
* @author jingshiyu
* @date 2019/7/17 17:39:36
* @desc
*/
public class MyCommentGenerator implements CommentGenerator {

/**
 \* The properties.
 */
private Properties properties;
/**
 \* The suppress date.
 */
private boolean suppressDate;
/**
 \* The suppress all comments.
 */
private boolean suppressAllComments;
/**
 \* 是否添加doc注释,true:不添加,false:添加<br>
 \* The addition of table remark's comments.
 \* If suppressAllComments is true, this option is ignored
 */
private boolean addRemarkComments;
private SimpleDateFormat dateFormat;
public MyCommentGenerator() {
    super();
    properties = new Properties();
    suppressDate = false;
    suppressAllComments = false;
    addRemarkComments = false;
}
@Override
public void addJavaFileComment(CompilationUnit compilationUnit) {
}
/**
 \* 实体类对应的mapper.xml注释,mapper类不加注释,如有需要参考 DefaultCommentGenerator
 */
@Override
public void addComment(XmlElement xmlElement) {
    if (suppressAllComments) {
        return;
    }
}
@Override
public void addRootComment(XmlElement rootElement) {
}
@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);
    }
}
protected void addJavadocTag(JavaElement javaElement, boolean markAsDoNotDelete) {
    javaElement.addJavaDocLine(" *");
    StringBuilder sb = new StringBuilder();
    sb.append(" \* ");
    sb.append(MergeConstants.NEW\_ELEMENT\_TAG);
    if (markAsDoNotDelete) {
        sb.append(" do\_not\_delete\_during\_merge");
    }
    String s = getDateString();
    if (s != null) {
        sb.append(' ');
        sb.append(s);
    }
    javaElement.addJavaDocLine(sb.toString());
}
protected String getDateString() {
    if (suppressDate) {
        return null;
    } else if (dateFormat != null) {
        return dateFormat.format(new Date());
    } else {
        return new Date().toString();
    }
}
/**
 \* 设置class的注解
 */
@Override
public void addClassComment(InnerClass innerClass, IntrospectedTable introspectedTable) {
    if (suppressAllComments) {
        return;
    }
    StringBuilder sb = new StringBuilder();
    innerClass.addJavaDocLine("/**");

// sb.append(" * This class corresponds to the database table ");

    sb.append(introspectedTable.getFullyQualifiedTable());
    innerClass.addJavaDocLine(sb.toString());
    addJavadocTag(innerClass, false);
    innerClass.addJavaDocLine(" */");
}
/**
 \* 方法注释
 */
@Override
public void addModelClassComment(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
    if (suppressAllComments || !addRemarkComments) {
        return;
    }
    StringBuilder sb = new StringBuilder();
    topLevelClass.addJavaDocLine("/**");
    //设置数据库的备注
    String remarks = introspectedTable.getRemarks();
    if (addRemarkComments && StringUtility.stringHasValue(remarks)) {
        topLevelClass.addJavaDocLine(" \* Database Table Remarks:");
        String\[\] remarkLines = remarks.split(System.getProperty("line.separator"));
        for (String remarkLine : remarkLines) {
            topLevelClass.addJavaDocLine(" \*   " \+ remarkLine);
        }
    }
    topLevelClass.addJavaDocLine(" *");
    sb.append(introspectedTable.getFullyQualifiedTable());
    topLevelClass.addJavaDocLine(sb.toString());
    addJavadocTag(topLevelClass, true);
    topLevelClass.addJavaDocLine(" */");
}
/**
 \* 添加枚举的注释
 */
@Override
public void addEnumComment(InnerEnum innerEnum, IntrospectedTable introspectedTable) {
    if (suppressAllComments) {
        return;
    }
    StringBuilder sb = new StringBuilder();
    innerEnum.addJavaDocLine("/**");
    sb.append(introspectedTable.getFullyQualifiedTable());
    innerEnum.addJavaDocLine(sb.toString());
    addJavadocTag(innerEnum, false);
    innerEnum.addJavaDocLine(" */");
}
/**
 \* 实体类字段注释
 */
@Override
public void addFieldComment(Field field, IntrospectedTable introspectedTable, IntrospectedColumn introspectedColumn) {
    if (suppressAllComments || StringUtils.isEmpty(introspectedColumn.getRemarks())) {
        return;
    }
    field.addJavaDocLine("/**");
    StringBuilder sb = new StringBuilder();
    //  introspectedColumn.getRemarks() 就是获取字段注释
    sb.append(" \* " \+ introspectedColumn.getRemarks());
    field.addJavaDocLine(sb.toString());
    field.addJavaDocLine(" */");
}
/**
 \* 实体类的静态字段
 */
@Override
public void addFieldComment(Field field, IntrospectedTable introspectedTable) {
    if (suppressAllComments) {
        return;
    }
}
/**
 \* 实体类toString方法
 */
@Override
public void addGeneralMethodComment(Method method, IntrospectedTable introspectedTable) {
    if (suppressAllComments) {
        return;
    }
}
/**
 \* 实体类getter方法注释
 */
@Override
public void addGetterComment(Method method, IntrospectedTable introspectedTable, IntrospectedColumn introspectedColumn) {
    if (suppressAllComments) {
        return;
    }
}
/**
 \* 实体类setter注释
 */
@Override
public void addSetterComment(Method method, IntrospectedTable introspectedTable, IntrospectedColumn introspectedColumn) {
    if (suppressAllComments) {
        return;
    }
}
/**
 \* 类注释
 \* @param innerClass
 \* @param introspectedTable
 \* @param markAsDoNotDelete
 */
@Override
public void addClassComment(InnerClass innerClass, IntrospectedTable introspectedTable, boolean markAsDoNotDelete) {
    if (suppressAllComments) {
        return;
    }
    StringBuilder sb = new StringBuilder();
    innerClass.addJavaDocLine("/**");
    sb.append(introspectedTable.getFullyQualifiedTable());
    innerClass.addJavaDocLine(sb.toString());
    addJavadocTag(innerClass, markAsDoNotDelete);
    innerClass.addJavaDocLine(" */");
}

}

调用

import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.config.Configuration;
import org.mybatis.generator.config.xml.ConfigurationParser;
import org.mybatis.generator.exception.InvalidConfigurationException;
import org.mybatis.generator.internal.DefaultShellCallback;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
/**
* java代码生成器(会生成example的entity)

* mybatis逆向工程
*
* @author jingshiyu
* @date 2019/7/17 17:24
* @desc java代码生成器(会生成example的entity)

*/
public class JavaExampleGenerator {

public static void main(String\[\] args) {
    List<String\> warnings = new ArrayList<String>();
    boolean overwrite = true;
    //如果这里出现空指针,直接写绝对路径即可。
    String genCfg = "/mbgConfiguration.xml";
    File configFile = new File(JavaExampleGenerator.class.getResource(genCfg).getFile());
    ConfigurationParser cp = new ConfigurationParser(warnings);
    Configuration config = null;
    try {
        config = cp.parseConfiguration(configFile);
    } catch (Exception e) {
        e.printStackTrace();
    }
    DefaultShellCallback callback = new DefaultShellCallback(overwrite);
    MyBatisGenerator myBatisGenerator = null;
    try {
        myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
    } catch (InvalidConfigurationException e) {
        e.printStackTrace();
    }
    try {
        myBatisGenerator.generate(null);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

}

来自为知笔记(Wiz)")

__EOF__

本文作者:ziyue7575
本文链接:https://www.cnblogs.com/ziyue7575/p/11608285.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐;)】一下。您的鼓励是博主的最大动力!


原网址: 访问
创建于: 2021-01-29 14:27:46
目录: default
标签: 无

请先后发表评论
  • 最新评论
  • 总共0条评论