Mybatis Generator是供開發者在mybatis開發時,快速構建mapper xml,mapper類,model類的一個插件工具。它相對來講對開發者是有很大的幫助的,可是它也有不足之處,好比生成的xml配置文件不是徹底能夠拿來使用的,有不少時候須要開發者自行修改後纔可使用。由於它仍是值得學習並使用的,所以有了本文的總結。html
環境說明:java
springboot2.0.2,mysql
mybatis-generator-plugin版本1.3.2,git
mysql-5.7.24-winx64web
<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屬性用來指定是否覆蓋本地已有文件。spring
爲了配置mybatis插件生成對應mapper相關文件,咱們須要定義一下數據表:jobitem。sql
-- ---------------------------- -- 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表。數據庫
項目結構以下:api
generatorConfig.xml配置內容以下:springboot
<?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>
到此爲止,全部的配置已完畢,若是在ecplise中使用,則右擊工程-》maven build...-》global添加命令mybatis-generator:generate-》運行,代碼生成完畢!
按照上邊配置完成後,會發現生成的model類,沒有數據註釋信息。但願將數據庫的備註自動生成到model屬性字段,以及setter/getter方法上。實際上這個想法是可行的,咱們須要自定義commentGenerator。
這裏必須這麼作,不然後邊會出現錯誤:自定義註釋類沒法初始化錯誤。
<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(" */"); } }
<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> 。。。
<?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> 。。。
此時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 XXXhttps://blog.csdn.net/u_ascend/article/details/80742919mybatis generator爲實體類生成自定義註釋(讀取數據庫字段的註釋添加到實體類,不修改源碼)https://blog.csdn.net/u012045045/article/details/83012681使用mybatis-generator添加自定義插件時提示沒法實例化插件類 Cannot instantiate object of typehttps://blog.csdn.net/twj13162380953/article/details/81286714Mybatis-generator自動生成代碼時候提取數據庫的字段註釋做爲實體類字段、getter/setter方法的註釋https://www.jianshu.com/p/7d58982a5b0bmybatis-generator自動生成代碼插件使用詳解https://www.cnblogs.com/handsomeye/p/6268513.html