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