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.bootgroupId><artifactId>spring-boot-maven-pluginartifactId>plugin><plugin><groupId>org.mybatis.generatorgroupId><artifactId>mybatis-generator-maven-pluginartifactId><version>1.3.2version><configuration><configurationFile>${basedir}/src/main/resources/generator/generatorConfig.xmlconfigurationFile><overwrite>trueoverwrite><verbose>trueverbose>configuration> plugin>。。。
这段maven配置内容的作用是用来导入mybatis-generator插件的&#xff0c;同时需要指定插件版本&#xff0c;以及mybatis generator生成配置文件路径。configuration->overwrite属性用来指定是否覆盖本地已有文件。
数据表构建&#xff1a;
为了配置mybatis插件生成对应mapper相关文件&#xff0c;我们需要定义一下数据表&#xff1a;jobitem。
-- ----------------------------
-- Table structure for &#96;jobitem&#96;
-- ----------------------------
DROP TABLE IF EXISTS &#96;jobitem&#96;;
CREATE TABLE &#96;jobitem&#96; (&#96;id&#96; bigint(20) NOT NULL AUTO_INCREMENT COMMENT &#39;唯一键 pk&#39;,&#96;appId&#96; varchar(32) NOT NULL COMMENT &#39;yarn任务id(applicationId)&#39;,&#96;submitFilePath&#96; varchar(256) NOT NULL COMMENT &#39;提交脚本路径&#39;,&#96;state&#96; varchar(16) DEFAULT NULL COMMENT &#39;任务状态&#39;,&#96;monitorType&#96; varchar(512) DEFAULT NULL COMMENT &#39;监控列表&#39;,&#96;createUserId&#96; varchar(32) NOT NULL COMMENT &#39;创建者关联Id&#39;,&#96;createUserName&#96; varchar(32) NOT NULL COMMENT &#39;创建者用户名&#39;,&#96;createTime&#96; datetime NOT NULL COMMENT &#39;创建时间&#39;,PRIMARY KEY (&#96;id&#96;),UNIQUE KEY &#96;key&#96; (&#96;appId&#96;)
) ENGINE&#61;InnoDB DEFAULT CHARSET&#61;utf8 COMMENT&#61;&#39;yarn任务持久化存储对象&#39;;-- ----------------------------
-- Records of jobitem
-- ----------------------------
这里的数据表是mysql下的表&#xff0c;在mysql下导入并生成jobitem表。
配置Mybatis配置文件&#xff08;/src/main/resources/generator/generatorConfig.xml&#xff09;&#xff1a;
项目结构如下&#xff1a;
generatorConfig.xml配置内容如下&#xff1a;
xml version&#61;"1.0" encoding&#61;"UTF-8"?>
DOCTYPE generatorConfigurationPUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN""http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd"><generatorConfiguration><classPathEntrylocation&#61;"D:\.m2\repository\mysql\mysql-connector-java\5.1.46\mysql-connector-java-5.1.46.jar" /><context id&#61;"Mysql" targetRuntime&#61;"MyBatis3Simple"defaultModelType&#61;"flat"><property name&#61;"beginningDelimiter" value&#61;"&#96;" /><property name&#61;"endingDelimiter" value&#61;"&#96;" /><property name&#61;"javaFileEncoding" value&#61;"UTF-8" /><property name&#61;"javaFormatter"value&#61;"org.mybatis.generator.api.dom.DefaultJavaFormatter" /><property name&#61;"xmlFormatter"value&#61;"org.mybatis.generator.api.dom.DefaultXmlFormatter" /><commentGenerator>commentGenerator><jdbcConnection driverClass&#61;"com.mysql.jdbc.Driver"connectionURL&#61;"jdbc:mysql://localhost:3306/mydb" userId&#61;"root"password&#61;"123456">jdbcConnection><javaModelGenerator targetPackage&#61;"com.dx.jobmonitor.model"targetProject&#61;"E:/work/git/...-model/src/main/java"><property name&#61;"enableSubPackages" value&#61;"true" /><property name&#61;"trimStrings" value&#61;"true" />javaModelGenerator><sqlMapGenerator targetPackage&#61;"mapper"targetProject&#61;"E:/work/git/f...-mapper/src/main/resources"><property name&#61;"enableSubPackages" value&#61;"true" />sqlMapGenerator><javaClientGenerator type&#61;"XMLMAPPER"targetPackage&#61;"com.dx.jobmonitor.mapper"targetProject&#61;"E:/work/git/feature-26692/。。。-mapper/src/main/java"><property name&#61;"enableSubPackages" value&#61;"true" />javaClientGenerator> <table tableName&#61;"sjmc_jobitem" enableCountByExample&#61;"false"enableDeleteByExample&#61;"false" enableDeleteByPrimaryKey&#61;"false"enableInsert&#61;"true" enableSelectByExample&#61;"true"enableUpdateByExample&#61;"true" enableUpdateByPrimaryKey&#61;"true"><generatedKey column&#61;"id" sqlStatement&#61;"Mysql"identity&#61;"true" />table>context>
generatorConfiguration>
运行mybatis generator插件&#xff0c;生成mapper类/mapper.xml/model类&#xff1a;
到此为止&#xff0c;所有的配置已完毕&#xff0c;如果在ecplise中使用&#xff0c;则右击工程-》maven build...-》global添加命令mybatis-generator:generate-》运行&#xff0c;代码生成完毕&#xff01;
自定义字段/getter/settetr注释
按照上边配置完成后&#xff0c;会发现生成的model类&#xff0c;没有数据注释信息。希望将数据库的备注自动生成到model属性字段&#xff0c;以及setter/getter方法上。实际上这个想法是可行的&#xff0c;我们需要自定义commentGenerator。
第一步&#xff1a;新建一个插件项目
这里必须这么做&#xff0c;否则后边会出现错误&#xff1a;自定义注释类无法初始化错误。
第二步&#xff1a;插件项目引入maven依赖
<dependencies><dependency><groupId>org.mybatis.generatorgroupId><artifactId>mybatis-generator-coreartifactId><version>1.3.2version>dependency><dependency><groupId>junitgroupId><artifactId>junitartifactId><version>3.8.1version><scope>testscope>dependency>dependencies>
第三步&#xff1a;添加自定义注释插件类&#xff1a;
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 &#61; new Properties();systemPro &#61; System.getProperties();suppressDate &#61; false;suppressAllComments &#61; false;nowTime &#61; (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 defaultreturn;}public void addConfigurationProperties(Properties properties) {this.properties.putAll(properties);suppressDate &#61; isTrue(properties.getProperty(PropertyRegistry.COMMENT_GENERATOR_SUPPRESS_DATE));suppressAllComments &#61; isTrue(properties.getProperty(PropertyRegistry.COMMENT_GENERATOR_SUPPRESS_ALL_COMMENTS));}/*** 判断传入参数是否为true* &#64;param property* &#64;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.* * &#64;param javaElement* the java element*/protected void addJavadocTag(JavaElement javaElement, boolean markAsDoNotDelete) {javaElement.addJavaDocLine(" *");StringBuilder sb &#61; new StringBuilder();sb.append(" * ");sb.append(MergeConstants.NEW_ELEMENT_TAG);if (markAsDoNotDelete) {sb.append(" do_not_delete_during_merge");}String s &#61; getDateString();if (s !&#61; null) {sb.append(&#39; &#39;);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.* * &#64;return a string representing the current timestamp, or null*/protected String getDateString() {String result &#61; null;if (!suppressDate) {result &#61; nowTime;}return result;}public void addClassComment(InnerClass innerClass, IntrospectedTable introspectedTable) {if (suppressAllComments) {return;}StringBuilder sb &#61; 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 &#61; 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 &#61; new StringBuilder(); field.addJavaDocLine("/**"); sb.append(" * "); sb.append(introspectedColumn.getRemarks()); sb.append("
\n"); sb.append(" * 列名:" &#43; introspectedColumn.getActualColumnName() &#43; " 类型:" &#43; introspectedColumn.getJdbcTypeName() &#43; "(" &#43; introspectedColumn.getLength() &#43; ")" &#43; " 允许空:" &#43; introspectedColumn.isNullable() &#43; " 缺省值:" &#43; introspectedColumn.getDefaultValue()); field.addJavaDocLine(sb.toString()); field.addJavaDocLine(" */"); }public void addFieldComment(Field field, IntrospectedTable introspectedTable) {if (suppressAllComments) {return;}StringBuilder sb &#61; 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 &#61; new StringBuilder();sb.append(" * ");sb.append(introspectedColumn.getRemarks());method.addJavaDocLine(sb.toString().replace("\n", " "));sb.setLength(0);//加入系统用户sb.append(" * &#64;author ");sb.append(systemPro.getProperty("user.name"));method.addJavaDocLine(sb.toString().replace("\n", " "));sb.setLength(0);//是否加入时间戳if(suppressDate){sb.append(" * &#64;date " &#43; nowTime);method.addJavaDocLine(sb.toString().replace("\n", " "));sb.setLength(0);}sb.append(" * &#64;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 &#61; new StringBuilder();sb.append(" * ");sb.append(introspectedColumn.getRemarks());method.addJavaDocLine(sb.toString().replace("\n", " "));sb.setLength(0);//加入系统用户sb.append(" * &#64;author ");sb.append(systemPro.getProperty("user.name"));method.addJavaDocLine(sb.toString().replace("\n", " "));sb.setLength(0);//是否加入时间戳if(suppressDate){sb.append(" * &#64;date " &#43; nowTime);method.addJavaDocLine(sb.toString().replace("\n", " "));sb.setLength(0);}Parameter parm &#61; method.getParameters().get(0);sb.append(" * &#64;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 &#61; new StringBuilder();innerClass.addJavaDocLine("/**");sb.append(" * ");sb.append(introspectedTable.getFullyQualifiedTable());innerClass.addJavaDocLine(sb.toString().replace("\n", " "));sb.setLength(0);sb.append(" * &#64;author ");sb.append(systemPro.getProperty("user.name"));sb.append(" ");sb.append(nowTime);innerClass.addJavaDocLine(" */");}}
第四步&#xff1a;修改*-web项目pom中mybatis-generator-plugin配置信息&#xff0c;导入自定义注释插件的依赖。
<plugins><plugin><groupId>org.springframework.bootgroupId><artifactId>spring-boot-maven-pluginartifactId>plugin><plugin><groupId>org.mybatis.generatorgroupId><artifactId>mybatis-generator-maven-pluginartifactId><version>1.3.2version><configuration><configurationFile>${basedir}/src/main/resources/generator/generatorConfig.xmlconfigurationFile><overwrite>trueoverwrite><verbose>trueverbose>configuration><dependencies><dependency><groupId>com.dx.jobmonitor.plugins.mybatisgroupId><artifactId>...-plugins-mybatisartifactId><version>1.0.0-SNAPSHOTversion><scope>systemscope><systemPath>E:/work/git/。。。-plugins-mybatis/target/...-plugins-mybatis-1.0.0-SNAPSHOT.jarsystemPath>dependency>dependencies>plugin>。。。
第五步&#xff1a;修改generatorConfig.xml配置文件给引入自定义注释类
xml version&#61;"1.0" encoding&#61;"UTF-8"?>
DOCTYPE generatorConfigurationPUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN""http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd"><generatorConfiguration><classPathEntrylocation&#61;"D:\.m2\repository\mysql\mysql-connector-java\5.1.46\mysql-connector-java-5.1.46.jar" /><context id&#61;"Mysql" targetRuntime&#61;"MyBatis3Simple"defaultModelType&#61;"flat">。。。<commentGeneratortype&#61;"com.boco.jobmonitor.plugins.mybatis.MyCommentGenerator">commentGenerator>。。。
第六步&#xff1a;重新运行mybatis-generator插件&#xff0c;生成mapper xml&#xff0c;mapper类&#xff0c;model类。
此时model类如下&#xff1a;
import java.util.Date;import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;public class Jobitem {/*** 唯一键 pk
* 列名:id 类型:INTEGER(10) 允许空:false 缺省值:null*/&#64;Id&#64;GeneratedValue(strategy &#61; GenerationType.IDENTITY)private Long id;/*** yarn任务id(applicationId)
* 列名:appId 类型:VARCHAR(32) 允许空:false 缺省值:null*/private String appid;/*** 提交脚本路径
* 列名:submitFilePath 类型:VARCHAR(256) 允许空:false 缺省值:null*/private String submitfilepath;/*** 任务状态
* 列名:state 类型:VARCHAR(16) 允许空:true 缺省值:null*/private String state;/*** 监控列表
* 列名:monitorType 类型:VARCHAR(512) 允许空:true 缺省值:null*/private String monitortype;/*** 创建者关联Id
* 列名:createUserId 类型:VARCHAR(32) 允许空:false 缺省值:null*/private String createuserid;/*** 创建者用户名
* 列名:createUserName 类型:VARCHAR(32) 允许空:false 缺省值:null*/private String createusername;/*** 创建时间
* 列名:createTime 类型:TIMESTAMP(19) 允许空:false 缺省值:null*/private Date createtime;/*** 唯一键 pk* * &#64;return id 唯一键 pk*/public Long getId() {return id;}/*** 唯一键 pk* * &#64;param id* 唯一键 pk*/public void setId(Long id) {this.id &#61; id;}/*** yarn任务id(applicationId)* * &#64;return appId yarn任务id(applicationId)*/public String getAppid() {return appid;}/*** yarn任务id(applicationId)* * &#64;param appid* yarn任务id(applicationId)*/public void setAppid(String appid) {this.appid &#61; appid &#61;&#61; null ? null : appid.trim();}/*** 提交脚本路径* * &#64;return submitFilePath 提交脚本路径*/public String getSubmitfilepath() {return submitfilepath;}/*** 提交脚本路径* * &#64;param submitfilepath* 提交脚本路径*/public void setSubmitfilepath(String submitfilepath) {this.submitfilepath &#61; submitfilepath &#61;&#61; null ? null : submitfilepath.trim();}/*** 任务状态* * &#64;return state 任务状态*/public String getState() {return state;}/*** 任务状态* * &#64;param state* 任务状态*/public void setState(String state) {this.state &#61; state &#61;&#61; null ? null : state.trim();}/*** 监控列表* * &#64;return monitorType 监控列表*/public String getMonitortype() {return monitortype;}/*** 监控列表* * &#64;param monitortype* 监控列表*/public void setMonitortype(String monitortype) {this.monitortype &#61; monitortype &#61;&#61; null ? null : monitortype.trim();}/*** 创建者关联Id* * &#64;return createUserId 创建者关联Id*/public String getCreateuserid() {return createuserid;}/*** 创建者关联Id* * &#64;param createuserid* 创建者关联Id*/public void setCreateuserid(String createuserid) {this.createuserid &#61; createuserid &#61;&#61; null ? null : createuserid.trim();}/*** 创建者用户名* * &#64;return createUserName 创建者用户名*/public String getCreateusername() {return createusername;}/*** 创建者用户名* * &#64;param createusername* 创建者用户名*/public void setCreateusername(String createusername) {this.createusername &#61; createusername &#61;&#61; null ? null : createusername.trim();}/*** 创建时间* * &#64;return createTime 创建时间*/public Date getCreatetime() {return createtime;}/*** 创建时间* * &#64;param createtime* 创建时间*/public void setCreatetime(Date createtime) {this.createtime &#61; createtime;}
}
参考&#xff1a;
mybatis插件--(1)--mybatis generator自定义插件或者扩展报Cannot instantiate object of type XXX
https://blog.csdn.net/u_ascend/article/details/80742919
mybatis generator为实体类生成自定义注释&#xff08;读取数据库字段的注释添加到实体类&#xff0c;不修改源码&#xff09;
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