SpringBoot(十一):springboot2.0.2下配置mybatis generator环境,并自定义字段/getter/settetr注释

Mybatis Generator是供开发者在mybatis开发时,快速构建mapper xml,mapper类,model类的一个插件工具。它相对来说对开发者是有很大的帮助的,但是它也有不足之处,比如生成的xml配置文件不是完全可以拿来使用的,有很多时候需要开发者自行修改后才可以使用。因为它还是值得学习并使用的,因此有了本文的总结。

环境说明:

springboot2.0.2,

mybatis-generator-plugin版本1.3.2,

mysql-5.7.24-winx64

Maven依赖导入:

<plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <!-- mybatis generator 自动生成代码插件 -->
            <plugin>
                <groupId>org.mybatis.generator</groupId>
                <artifactId>mybatis-generator-maven-plugin</artifactId>
                <version>1.3.2</version>
                <configuration>
                    <configurationFile>${basedir}/src/main/resources/generator/generatorConfig.xml</configurationFile>
                    <overwrite>true</overwrite>
                    <verbose>true</verbose>
                </configuration>                
            </plugin>
            。。。

这段maven配置内容的作用是用来导入mybatis-generator插件的,同时需要指定插件版本,以及mybatis generator生成配置文件路径。configuration->overwrite属性用来指定是否覆盖本地已有文件。

数据表构建:

为了配置mybatis插件生成对应mapper相关文件,我们需要定义一下数据表:jobitem。

-- ----------------------------
-- Table structure for `jobitem`
-- ----------------------------
DROP TABLE IF EXISTS `jobitem`;
CREATE TABLE `jobitem` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '唯一键 pk',
  `appId` varchar(32) NOT NULL COMMENT 'yarn任务id(applicationId)',
  `submitFilePath` varchar(256) NOT NULL COMMENT '提交脚本路径',
  `state` varchar(16) DEFAULT NULL COMMENT '任务状态',
  `monitorType` varchar(512) DEFAULT NULL COMMENT '监控列表',
  `createUserId` varchar(32) NOT NULL COMMENT '创建者关联Id',
  `createUserName` varchar(32) NOT NULL COMMENT '创建者用户名',
  `createTime` datetime NOT NULL COMMENT '创建时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `key` (`appId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='yarn任务持久化存储对象';

-- ----------------------------
-- Records of jobitem
-- ----------------------------

 这里的数据表是mysql下的表,在mysql下导入并生成jobitem表。

配置Mybatis配置文件(/src/main/resources/generator/generatorConfig.xml):

项目结构如下:

generatorConfig.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">

<generatorConfiguration>
    <!-- 数据库驱动包位置 -->
    <classPathEntry
        location="D:\.m2\repository\mysql\mysql-connector-java\5.1.46\mysql-connector-java-5.1.46.jar" />
    <context id="Mysql" targetRuntime="MyBatis3Simple"
        defaultModelType="flat">
        <!-- ( property*,plugin*, commentGenerator?, jdbcConnection, javaTypeResolver?, 
            javaModelGenerator, sqlMapGenerator?, javaClientGenerator?, table+ ) -->

        <property name="beginningDelimiter" value="`" />
        <property name="endingDelimiter" value="`" />

        <!-- 生成的 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" />

        <!-- 自定义注释生成器 -->
        <commentGenerator>
        </commentGenerator>

        <!--<plugin type="tk.mybatis.mapper.generator.MapperPlugin"> <property 
            name="mappers" value="com.ad.core.mapper"/> </plugin> -->

        <!-- 连接 那个知道把参数改为 ${}的形式,并且用的yml的 -->
        <jdbcConnection driverClass="com.mysql.jdbc.Driver"
            connectionURL="jdbc:mysql://localhost:3306/mydb" userId="root"
            password="123456">
        </jdbcConnection>

        <!--生成Model类存放位置 -->
        <javaModelGenerator targetPackage="com.dx.jobmonitor.model"
            targetProject="E:/work/git/...-model/src/main/java">
            <property name="enableSubPackages" value="true" />
            <property name="trimStrings" value="true" />
        </javaModelGenerator>

        <!--生成mapper.xml配置文件位置 -->
        <sqlMapGenerator targetPackage="mapper"
            targetProject="E:/work/git/f...-mapper/src/main/resources">
            <property name="enableSubPackages" value="true" />
        </sqlMapGenerator>

        <!-- 生成mapper接口文件位置  -->
        <javaClientGenerator type="XMLMAPPER"
            targetPackage="com.dx.jobmonitor.mapper"
            targetProject="E:/work/git/feature-26692/。。。-mapper/src/main/java">
            <property name="enableSubPackages" value="true" />
        </javaClientGenerator>

        <!-- 
        (已经自定义修改了某些sql语句,因此如果重新生成导致sql被覆盖)需要生成的实体类对应的表名,多个实体类复制多份该配置即可
        --> 
        <table tableName="sjmc_jobitem" enableCountByExample="false"
            enableDeleteByExample="false" enableDeleteByPrimaryKey="false"
            enableInsert="true" enableSelectByExample="true"
            enableUpdateByExample="true" enableUpdateByPrimaryKey="true">
            <generatedKey column="id" sqlStatement="Mysql"
                identity="true" />
        </table>
    </context>
</generatorConfiguration>

运行mybatis generator插件,生成mapper类/mapper.xml/model类:

 到此为止,所有的配置已完毕,如果在ecplise中使用,则右击工程-》maven build...-》global添加命令mybatis-generator:generate-》运行,代码生成完毕!

自定义字段/getter/settetr注释

按照上边配置完成后,会发现生成的model类,没有数据注释信息。希望将数据库的备注自动生成到model属性字段,以及setter/getter方法上。实际上这个想法是可行的,我们需要自定义commentGenerator。

第一步:新建一个插件项目

这里必须这么做,否则后边会出现错误:自定义注释类无法初始化错误。

第二步:插件项目引入maven依赖

    <dependencies>
        <dependency>
            <groupId>org.mybatis.generator</groupId>
            <artifactId>mybatis-generator-core</artifactId>
            <version>1.3.2</version>
        </dependency>
        
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

第三步:添加自定义注释插件类:

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Properties;

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.CompilationUnit;
import org.mybatis.generator.api.dom.java.Field;
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.xml.XmlElement;
import org.mybatis.generator.config.MergeConstants;
import org.mybatis.generator.config.PropertyRegistry;

/**
 * 自定义实现 注释生成器 CommentGenerator 接口
 */
public class MyCommentGenerator implements CommentGenerator {
    private Properties properties;
    private Properties systemPro;
    private boolean suppressDate;
    private boolean suppressAllComments;
    private String nowTime;

    public MyCommentGenerator() {
        super();
        properties = new Properties();
        systemPro = System.getProperties();
        suppressDate = false;
        suppressAllComments = false;
        nowTime = (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")).format(new Date());
    }

    public void addJavaFileComment(CompilationUnit compilationUnit) {
        if (suppressAllComments) {
            return;
        }
        return;
    }

    /**
     * Adds a suitable comment to warn users that the element was generated, and
     * when it was generated.
     */
    public void addComment(XmlElement xmlElement) {
        return;
    }

    public void addRootComment(XmlElement rootElement) {
        // add no document level comments by default
        return;
    }

    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));
    }
    
    /**
     * 判断传入参数是否为true
     * @param property
     * @return
     */
    private boolean isTrue(String property) {
        if("true".equals(property)){
            return true;
        }
        return false;
    }

    /**
     * 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
     */
    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());
    }

    /**
     * This method 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() {
        String result = null;
        if (!suppressDate) {
            result = nowTime;
        }
        return result;
    }

    public void addClassComment(InnerClass innerClass, IntrospectedTable introspectedTable) {
        if (suppressAllComments) {
            return;
        }
        StringBuilder sb = new StringBuilder();
        innerClass.addJavaDocLine("/**");
        sb.append(" * ");
        sb.append(introspectedTable.getFullyQualifiedTable());
        sb.append(" ");
        sb.append(getDateString());
        innerClass.addJavaDocLine(sb.toString().replace("\n", " "));
        innerClass.addJavaDocLine(" */");
    }

    public void addEnumComment(InnerEnum innerEnum, IntrospectedTable introspectedTable) {
        if (suppressAllComments) {
            return;
        }
        StringBuilder sb = new StringBuilder();
        innerEnum.addJavaDocLine("/**");
        sb.append(" * ");
        sb.append(introspectedTable.getFullyQualifiedTable());
        innerEnum.addJavaDocLine(sb.toString().replace("\n", " "));
        innerEnum.addJavaDocLine(" */");
    }
    
    /**
     * 设置字段注释
     */
    public void addFieldComment(Field field, IntrospectedTable introspectedTable, IntrospectedColumn introspectedColumn) {
        if (suppressAllComments) {
            return;
        }
        StringBuilder sb = new StringBuilder(); 
        field.addJavaDocLine("/**"); 
        sb.append(" * "); 
        sb.append(introspectedColumn.getRemarks()); 
        sb.append("<br> \n"); 
        sb.append("    * 列名:" + introspectedColumn.getActualColumnName() + " 类型:" + introspectedColumn.getJdbcTypeName() 
        + "(" + introspectedColumn.getLength() + ")" + " 允许空:" + introspectedColumn.isNullable() + " 缺省值:" 
        + introspectedColumn.getDefaultValue()); 
        field.addJavaDocLine(sb.toString()); 
        field.addJavaDocLine(" */"); 
    }

    public void addFieldComment(Field field, IntrospectedTable introspectedTable) {
        if (suppressAllComments) {
            return;
        }
        StringBuilder sb = new StringBuilder();
        field.addJavaDocLine("/**");
        sb.append(" * ");
        sb.append(introspectedTable.getFullyQualifiedTable());
        field.addJavaDocLine(sb.toString().replace("\n", " "));
        field.addJavaDocLine(" */");
    }

    public void addGeneralMethodComment(Method method, IntrospectedTable introspectedTable) {
        if (suppressAllComments) {
            return;
        }
      method.addJavaDocLine("/**");
      addJavadocTag(method, false);
      method.addJavaDocLine(" */");
    }
    
    /**
     * 设置getter方法注释
     */
    public void addGetterComment(Method method, IntrospectedTable introspectedTable,
            IntrospectedColumn introspectedColumn) {
        if (suppressAllComments) {
            return;
        }
        method.addJavaDocLine("/**");
        StringBuilder sb = new StringBuilder();
        sb.append(" * ");
        sb.append(introspectedColumn.getRemarks());
        method.addJavaDocLine(sb.toString().replace("\n", " "));
        sb.setLength(0);
        
        //加入系统用户
        sb.append(" * @author ");
        sb.append(systemPro.getProperty("user.name"));
        method.addJavaDocLine(sb.toString().replace("\n", " "));
        sb.setLength(0);
        
        //是否加入时间戳
        if(suppressDate){
            sb.append(" * @date " + nowTime);
            method.addJavaDocLine(sb.toString().replace("\n", " "));
            sb.setLength(0);
        }
        
        sb.append(" * @return ");
        sb.append(introspectedColumn.getActualColumnName());
        sb.append(" ");
        sb.append(introspectedColumn.getRemarks());
        method.addJavaDocLine(sb.toString().replace("\n", " "));
        method.addJavaDocLine(" */");
    }
    
    /**
     * 设置setter方法注释
     */
    public void addSetterComment(Method method, IntrospectedTable introspectedTable,
            IntrospectedColumn introspectedColumn) {
        if (suppressAllComments) {
            return;
        }
        method.addJavaDocLine("/**");
        StringBuilder sb = new StringBuilder();
        sb.append(" * ");
        sb.append(introspectedColumn.getRemarks());
        method.addJavaDocLine(sb.toString().replace("\n", " "));
        sb.setLength(0);
        
        //加入系统用户
        sb.append(" * @author ");
        sb.append(systemPro.getProperty("user.name"));
        method.addJavaDocLine(sb.toString().replace("\n", " "));
        sb.setLength(0);
        
        //是否加入时间戳
        if(suppressDate){
            sb.append(" * @date " + nowTime);
            method.addJavaDocLine(sb.toString().replace("\n", " "));
            sb.setLength(0);
        }
        
        Parameter parm = method.getParameters().get(0);
        sb.append(" * @param ");
        sb.append(parm.getName());
        sb.append(" ");
        sb.append(introspectedColumn.getRemarks());
        method.addJavaDocLine(sb.toString().replace("\n", " "));
        method.addJavaDocLine(" */");
    }

    public void addClassComment(InnerClass innerClass, IntrospectedTable introspectedTable, boolean markAsDoNotDelete) {
        if (suppressAllComments) {
            return;
        }
        StringBuilder sb = new StringBuilder();
        innerClass.addJavaDocLine("/**");
        sb.append(" * ");
        sb.append(introspectedTable.getFullyQualifiedTable());
        innerClass.addJavaDocLine(sb.toString().replace("\n", " "));
        sb.setLength(0);
        sb.append(" * @author ");
        sb.append(systemPro.getProperty("user.name"));
        sb.append(" ");
        sb.append(nowTime);
        innerClass.addJavaDocLine(" */");
    }
    
}

第四步:修改*-web项目pom中mybatis-generator-plugin配置信息,导入自定义注释插件的依赖。

<plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <!-- mybatis generator 自动生成代码插件 -->
            <plugin>
                <groupId>org.mybatis.generator</groupId>
                <artifactId>mybatis-generator-maven-plugin</artifactId>
                <version>1.3.2</version>
                <configuration>
                    <configurationFile>${basedir}/src/main/resources/generator/generatorConfig.xml</configurationFile>
                    <overwrite>true</overwrite>
                    <verbose>true</verbose>
                </configuration>
                <dependencies>
                    <dependency>
                        <groupId>com.dx.jobmonitor.plugins.mybatis</groupId>
                        <artifactId>...-plugins-mybatis</artifactId>
                        <version>1.0.0-SNAPSHOT</version>
                        <scope>system</scope>
                        <systemPath>E:/work/git/。。。-plugins-mybatis/target/...-plugins-mybatis-1.0.0-SNAPSHOT.jar</systemPath>
                    </dependency>
                </dependencies>
            </plugin>
            。。。

第五步:修改generatorConfig.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">

<generatorConfiguration>
    <!-- 数据库驱动包位置 -->
    <classPathEntry
        location="D:\.m2\repository\mysql\mysql-connector-java\5.1.46\mysql-connector-java-5.1.46.jar" />
    <context id="Mysql" targetRuntime="MyBatis3Simple"
        defaultModelType="flat">
        。。。
        <!-- 自定义注释生成器 -->
        <commentGenerator
            type="com.boco.jobmonitor.plugins.mybatis.MyCommentGenerator">
        </commentGenerator>
       。。。

第六步:重新运行mybatis-generator插件,生成mapper xml,mapper类,model类。

此时model类如下:

import java.util.Date;

import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

public class Jobitem {
    /**
     * 唯一键 pk<br>
     * 列名:id 类型:INTEGER(10) 允许空:false 缺省值:null
     */
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    /**
     * yarn任务id(applicationId)<br>
     * 列名:appId 类型:VARCHAR(32) 允许空:false 缺省值:null
     */
    private String appid;

    /**
     * 提交脚本路径<br>
     * 列名:submitFilePath 类型:VARCHAR(256) 允许空:false 缺省值:null
     */
    private String submitfilepath;

    /**
     * 任务状态<br>
     * 列名:state 类型:VARCHAR(16) 允许空:true 缺省值:null
     */
    private String state;

    /**
     * 监控列表<br>
     * 列名:monitorType 类型:VARCHAR(512) 允许空:true 缺省值:null
     */
    private String monitortype;

    /**
     * 创建者关联Id<br>
     * 列名:createUserId 类型:VARCHAR(32) 允许空:false 缺省值:null
     */
    private String createuserid;

    /**
     * 创建者用户名<br>
     * 列名:createUserName 类型:VARCHAR(32) 允许空:false 缺省值:null
     */
    private String createusername;

    /**
     * 创建时间<br>
     * 列名:createTime 类型:TIMESTAMP(19) 允许空:false 缺省值:null
     */
    private Date createtime;


    /**
     * 唯一键 pk
     * 
     * @return id 唯一键 pk
     */
    public Long getId() {
        return id;
    }

    /**
     * 唯一键 pk
     * 
     * @param id
     *            唯一键 pk
     */
    public void setId(Long id) {
        this.id = id;
    }

    /**
     * yarn任务id(applicationId)
     * 
     * @return appId yarn任务id(applicationId)
     */
    public String getAppid() {
        return appid;
    }

    /**
     * yarn任务id(applicationId)
     * 
     * @param appid
     *            yarn任务id(applicationId)
     */
    public void setAppid(String appid) {
        this.appid = appid == null ? null : appid.trim();
    }

    /**
     * 提交脚本路径
     * 
     * @return submitFilePath 提交脚本路径
     */
    public String getSubmitfilepath() {
        return submitfilepath;
    }

    /**
     * 提交脚本路径
     * 
     * @param submitfilepath
     *            提交脚本路径
     */
    public void setSubmitfilepath(String submitfilepath) {
        this.submitfilepath = submitfilepath == null ? null : submitfilepath.trim();
    }

    /**
     * 任务状态
     * 
     * @return state 任务状态
     */
    public String getState() {
        return state;
    }

    /**
     * 任务状态
     * 
     * @param state
     *            任务状态
     */
    public void setState(String state) {
        this.state = state == null ? null : state.trim();
    }

    /**
     * 监控列表
     * 
     * @return monitorType 监控列表
     */
    public String getMonitortype() {
        return monitortype;
    }

    /**
     * 监控列表
     * 
     * @param monitortype
     *            监控列表
     */
    public void setMonitortype(String monitortype) {
        this.monitortype = monitortype == null ? null : monitortype.trim();
    }

    /**
     * 创建者关联Id
     * 
     * @return createUserId 创建者关联Id
     */
    public String getCreateuserid() {
        return createuserid;
    }

    /**
     * 创建者关联Id
     * 
     * @param createuserid
     *            创建者关联Id
     */
    public void setCreateuserid(String createuserid) {
        this.createuserid = createuserid == null ? null : createuserid.trim();
    }

    /**
     * 创建者用户名
     * 
     * @return createUserName 创建者用户名
     */
    public String getCreateusername() {
        return createusername;
    }

    /**
     * 创建者用户名
     * 
     * @param createusername
     *            创建者用户名
     */
    public void setCreateusername(String createusername) {
        this.createusername = createusername == null ? null : createusername.trim();
    }

    /**
     * 创建时间
     * 
     * @return createTime 创建时间
     */
    public Date getCreatetime() {
        return createtime;
    }

    /**
     * 创建时间
     * 
     * @param createtime
     *            创建时间
     */
    public void setCreatetime(Date createtime) {
        this.createtime = createtime;
    }
}

参考:

mybatis插件--(1)--mybatis generator自定义插件或者扩展报Cannot instantiate object of type XXX
https://blog.csdn.net/u_ascend/article/details/80742919

mybatis generator为实体类生成自定义注释(读取数据库字段的注释添加到实体类,不修改源码)
https://blog.csdn.net/u012045045/article/details/83012681

使用mybatis-generator添加自定义插件时提示无法实例化插件类 Cannot instantiate object of type
https://blog.csdn.net/twj13162380953/article/details/81286714

Mybatis-generator自动生成代码时候提取数据库的字段注释作为实体类字段、getter/setter方法的注释
https://www.jianshu.com/p/7d58982a5b0b

mybatis-generator自动生成代码插件使用详解
https://www.cnblogs.com/handsomeye/p/6268513.html


 

posted @ 2019-02-18 18:57  cctext  阅读(1461)  评论(0编辑  收藏  举报