tags: [mybatis, mybatis generator]
categories: [mybatis]
前言
实际开发之中,虽然有很多CRUD工具,但是使用最多的还是Mybatis,而Mybatis Gerator可以帮助你自动生成基本的单表CRUD代码,提高效率
但是生成的代码有些地方已经不符合当前的风格和标准,比如现在很多项目都是使用lombok,而不是在实体类里面添加get/set方法,默认生成的注释信息不友好,这个时候我们可以通过一些修改来生成我们想要的结果
使用
引入依赖
后边的Plugn是以Maven生成的,若以代码形式来生成则无需配置
<!--mybatis--><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId></dependency><!-- https://mvnrepository.com/artifact/org.mybatis.generator/mybatis-generator-core --><dependency><groupId>org.mybatis.generator</groupId><artifactId>mybatis-generator-core</artifactId><version>1.3.7</version></dependency><plugin><groupId>org.mybatis.generator</groupId><artifactId>mybatis-generator-maven-plugin</artifactId><version>1.3.7</version><configuration><!--自定义路径,否则会自动识别GeneratorConfig.xml文件--><!-- <configurationFiile>${basedir}/src/main/resources/generatorConfig.xml</configurationFile>--><!--是为了运行mvn mybatis-generator:generate -e时显示具体过程--><verbose>true</verbose><!--为了生成文件时后一次生成的文件覆盖前一次生成的同名文件--><overwrite>true</overwrite></configuration><dependencies><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.44</version></dependency></dependencies></plugin>
后边的Plugn是以Maven生成需要配置的,若以代码形式来生成则无需配置
我的存放目录如下
添加自定义插件
package com.bwensun.common.mybatis;import org.mybatis.generator.api.IntrospectedColumn;import org.mybatis.generator.api.IntrospectedTable;import org.mybatis.generator.api.PluginAdapter;import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;import org.mybatis.generator.api.dom.java.Interface;import org.mybatis.generator.api.dom.java.Method;import org.mybatis.generator.api.dom.java.TopLevelClass;import java.text.SimpleDateFormat;import java.util.Date;import java.util.List;/*** lombok插件** @author bwensun* @date 2019/12/16*/public class LombokPlugin extends PluginAdapter {@Overridepublic boolean validate(List<String> warnings) {return true;}@Overridepublic boolean clientGenerated(Interface interfaze, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {SimpleDateFormat dateFormatter = new SimpleDateFormat(properties.getProperty("dateFormat", "yyyy-MM-dd"));//接口添加注释interfaze.addJavaDocLine("/**");interfaze.addJavaDocLine(" * " + introspectedTable.getRemarks());interfaze.addJavaDocLine(" *");interfaze.addJavaDocLine(" * @author " + properties.getProperty("author"));interfaze.addJavaDocLine(" * @date " + dateFormatter.format(new Date()));interfaze.addJavaDocLine(" */");//dao添加注解addAnnotations(interfaze, "org.springframework.stereotype.Repository", "@Repository");return true;}@Overridepublic boolean modelBaseRecordClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {if (Boolean.parseBoolean(this.properties.getProperty("data"))) {addAnnotations(topLevelClass, "lombok.Data", "@Data");} else {addAnnotations(topLevelClass, "lombok.Getter", "@Getter");addAnnotations(topLevelClass, "lombok.Setter", "@Setter");addAnnotations(topLevelClass, "lombok.ToString", "@ToString");}if (Boolean.parseBoolean(this.properties.getProperty("builder"))) {addAnnotations(topLevelClass, "lombok.Builder", "@Builder");}return true;}/*** 关闭get方法生成*/@Overridepublic boolean modelGetterMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedColumn introspectedColumn, IntrospectedTable introspectedTable, ModelClassType modelClassType) {return false;}/*** 关闭set方法生成*/@Overridepublic boolean modelSetterMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedColumn introspectedColumn, IntrospectedTable introspectedTable, ModelClassType modelClassType) {return false;}public void addSwaggerAnnotation(){}/*** 设置类注解** @param importedType 导包类型* @param annotation 注解*/private void addAnnotations(TopLevelClass topLevelClass, String importedType, String annotation) {topLevelClass.addImportedType(importedType);topLevelClass.addAnnotation(annotation);}/*** 设置接口注解** @param importedType 导包类型* @param annotation 注解*/private void addAnnotations(Interface interfaze, String importedType, String annotation) {interfaze.addImportedType(new FullyQualifiedJavaType(importedType));interfaze.addAnnotation(annotation);}private String date2Str(Date date) {SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd");return format.format(date);}}
说明
Mybatis Generator的配置文件中包含了plugn标签,我们就可以通过手写插件来实现我们自己的功能,
重写注释部分注释方法
package com.bwensun.common.mybatis;import org.mybatis.generator.api.IntrospectedColumn;import org.mybatis.generator.api.IntrospectedTable;import org.mybatis.generator.api.dom.java.*;import org.mybatis.generator.internal.DefaultCommentGenerator;import org.mybatis.generator.internal.util.StringUtility;import java.text.SimpleDateFormat;import java.util.Date;import java.util.List;import java.util.Properties;import java.util.Set;/*** 增加 swagger 字段注释支持** @author daiwenzh5* @date 2019/9/8 18:56*/public class CustomCommentGenerator extends DefaultCommentGenerator {private Properties properties;public CustomCommentGenerator() {properties = new Properties();}@Overridepublic void addConfigurationProperties(Properties properties) {// 获取自定义的 propertiesthis.properties.putAll(properties);}/*** 添加 swagger 字段注解** @param field 字段* @param introspectedTable 表* @param introspectedColumn 列* @param imports 导入类*/@Overridepublic void addFieldAnnotation(Field field, IntrospectedTable introspectedTable, IntrospectedColumn introspectedColumn, Set<FullyQualifiedJavaType> imports) {imports.add(new FullyQualifiedJavaType("io.swagger.annotations.ApiModelProperty"));String remarks = introspectedColumn.getRemarks();field.addAnnotation(this.getSwaggerAnnotation(field.getName(), remarks));super.addFieldAnnotation(field, introspectedTable, introspectedColumn, imports);}@Overridepublic void addFieldAnnotation(Field field, IntrospectedTable introspectedTable, Set<FullyQualifiedJavaType> set) {super.addFieldAnnotation(field, introspectedTable, set);}@Overridepublic void addFieldComment(Field field, IntrospectedTable introspectedTable, IntrospectedColumn introspectedColumn) {// 获取字段注释String remarks = introspectedColumn.getRemarks();field.addJavaDocLine("/**");field.addJavaDocLine(" * " + remarks);field.addJavaDocLine(" */");}@Overridepublic void addGeneralMethodComment(Method method, IntrospectedTable introspectedTable) {/* if (suppressAllComments) {return;}*/String methodDoc = getMethodDoc(method, introspectedTable);method.addJavaDocLine("/**");method.addJavaDocLine(" * " + methodDoc);method.addJavaDocLine(" *");setMethodParam(method);setMethodReturn(method, introspectedTable);method.addJavaDocLine(" */");}@Overridepublic void addClassAnnotation(InnerClass innerClass, IntrospectedTable introspectedTable, Set<FullyQualifiedJavaType> set) {super.addClassAnnotation(innerClass, introspectedTable, set);}@Overridepublic void addModelClassComment(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {String author = properties.getProperty("author");String dateFormat = properties.getProperty("dateFormat", "yyyy-MM-dd");SimpleDateFormat dateFormatter = new SimpleDateFormat(dateFormat);// 获取表注释String remarks = introspectedTable.getRemarks();topLevelClass.addJavaDocLine("/**");topLevelClass.addJavaDocLine(" * " + remarks);topLevelClass.addJavaDocLine(" *");topLevelClass.addJavaDocLine(" * @author " + author);topLevelClass.addJavaDocLine(" * @date " + dateFormatter.format(new Date()));topLevelClass.addJavaDocLine(" */");}/*** 获取 swagger 注解信息** @param name 字段名* @param remarks 注释信息* @return 返回 swagger 注释字符串*/private String getSwaggerAnnotation(String name, String remarks) {StringBuffer buffer = new StringBuffer("@ApiModelProperty(");buffer.append("name = \"");buffer.append(name);if (StringUtility.stringHasValue(remarks)) {buffer.append("\", value = \"");buffer.append(remarks);}buffer.append("\")");return buffer.toString();}private String getMethodDoc(Method method, IntrospectedTable introspectedTable) {String remarks = introspectedTable.getRemarks();String methodDoc;switch (method.getName()){case "deleteByPrimaryKey":methodDoc = ("根据主键删除" + remarks + "记录");break;case "selectByPrimaryKey":methodDoc = ("根据主键查询" + remarks + "记录");break;case "insert":methodDoc = ("新增记录至" + remarks);break;case "selectAll":methodDoc = ("查询" + remarks + "所有记录");break;case "updateByPrimaryKey":methodDoc = ("根据主键更新" + remarks + "记录");break;default:methodDoc = "description";break;}return methodDoc;}/*** 设置参数注释** @param method 方法*/private void setMethodParam(Method method) {List<Parameter> parameters = method.getParameters();if (parameters.size() != 0){parameters.forEach(x ->method.addJavaDocLine(" * @param " + x.getName() + ("ID".equalsIgnoreCase(x.getName())?" 主键":" 记录") ));}}/*** 设置返回值注释** @param method 方法* @param introspectedTable 表对象*/private void setMethodReturn(Method method, IntrospectedTable introspectedTable) {String methodReturn;String shortName = method.getReturnType().getShortName();if ("int".equalsIgnoreCase(shortName)){methodReturn = "受影响的记录数";}else if (shortName.startsWith("java.util.List")){methodReturn = introspectedTable.getRemarks() + "list";}else {methodReturn = introspectedTable.getRemarks() + "记录";}method.addJavaDocLine(" * @return " + methodReturn);}}
配置文件配置
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE generatorConfigurationPUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN""http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd"><generatorConfiguration><!-- 数据库驱动:选择你的本地硬盘上面的数据库驱动包--><classPathEntry location="D:\ProgramFile\maven\maven_repository\mysql\mysql-connector-java\5.1.44\mysql-connector-java-5.1.44.jar"/><context id="CustomGenerator" defaultModelType="hierarchical" targetRuntime="MyBatis3Simple"><property name="autoDelimitKeywords" value="false"/><plugin type="org.mybatis.generator.plugins.SerializablePlugin"/><!-- 插件 --><plugin type="com.bwensun.common.mybatis.LombokPlugin"><property name="author" value="bwensun"/><property name="builder" value="false"/><property name="data" value="false"/></plugin><commentGenerator type = "com.bwensun.common.mybatis.CustomCommentGenerator"><property name="javaFileEncoding" value="UTF-8"/><property name="suppressDate" value="true" /><property name="suppressAllComments" value="false" /><property name="author" value="郑建雄"/><property name="dateFormat" value="yyyy/MM/dd"/></commentGenerator><!--数据库链接URL,用户名、密码 --><jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://127.0.0.1:3306/blog?useSSL=true"userId="root" password="285413"><property name="useInformationSchema" value="true" /></jdbcConnection><javaTypeResolver><property name="forceBigDecimals" value="false"/></javaTypeResolver><!-- 生成模型的包名和位置--><javaModelGenerator targetPackage="com.bwensun.blog.domain" targetProject="BLOG_API/src/main/java"><!-- 是否允许子包,即targetPackage.schemaName.tableName --><property name="enableSubPackages" value="true"/><!-- 是否对model添加 构造函数 --><property name="constructorBased" value="false"/><!-- 是否对类CHAR类型的列的数据进行trim操作 --><property name="trimStrings" value="true"/><!-- 建立的Model对象是否 不可改变 即生成的Model对象不会有 setter方法,只有构造方法 --><!--<property name="immutable" value="false"/>--></javaModelGenerator><!-- 生成映射文件的包名和位置--><sqlMapGenerator targetPackage="mapper" targetProject="BLOG_USER_SERVICE/src/main/resources"><property name="enableSubPackages" value="false"/></sqlMapGenerator><!-- 生成DAO的包名和位置--><javaClientGenerator type="XMLMAPPER" targetPackage="com.bwensun.repository"targetProject="BLOG_USER_SERVICE/src/main/java"><property name="enableSubPackages" value="false"/></javaClientGenerator><!-->要生成的表 tableName是数据库中的表名或视图名 domainObjectName是实体类名<--><table tableName="USER" domainObjectName="User" enableCountByExample="false" enableUpdateByExample="false"enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"></table></context></generatorConfiguration>
执行生成代码
/*** @author bwensun* @date 2019/12/17*/public class MybatisGenerator {public static void main(String[] args) {String path = "D:\\ProgramFile\\idea_workspace\\DUBBO_TEST\\BLOG\\BLOG_USER_SERVICE\\src\\main\\resources\\generatorConfig.xml";args = new String[]{"-configfile", path, "-overwrite"};ShellRunner.main(args);}}
