mybatis-generator自定义实现生成entity,xml含中文注释

mybatis-generator逆向工程生成代码

mybatis-generator只能生成entity,xml,这里实现entity,xml,service,controller,支持注解和xml方式
gitee代码路径 mybatis-generator

方法1. 自定义实现CommentGenerator
package com.yl.ext;

import org.apache.commons.lang3.StringUtils;
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.*;
import org.mybatis.generator.internal.util.StringUtility;

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

/**
 * 自定义实现代码生成时,包含中文注释
 * <pre>
 *  mybatis-generator 默认注释实现类 {@link  org.mybatis.generator.internal.DefaultCommentGenerator }
 *  生成英文注释,不美观,并且不是表字段注释
 *  配置方式
 *      &lt;commentGenerator type="com.yl.ext.ZhCnCommentGenerator"&gt;
 *         &lt;property name="suppressDate" value="false" /&gt;
 *         &lt;property name="suppressAllComments" value="false" /&gt;
 *       &lt;/commentGenerator&gt;
 * </pre>
 *
 * @author liuxubo
 * @date 2023/7/5 11:44
 */
public class ZhCnCommentGenerator implements CommentGenerator {
    private final Properties properties = new Properties();
    private Properties systemPro = System.getProperties();

    /**
     * 控制类上注释中是否生成日期
     */
    private boolean suppressDate;
    private boolean suppressAllComments;
    /**
     * 类上注释
     */
    private boolean suppressClassComments = false;

    /**
     * 日期格式
     */
    private String dateTimeFormat = "yyyy/MM/dd HH:mm";


    private String currentDateStr;


    public ZhCnCommentGenerator() {
        super();
        suppressDate = false;
        suppressAllComments = false;
        currentDateStr = new SimpleDateFormat(dateTimeFormat).format(new Date());
    }

    @Override
    public void addConfigurationProperties(Properties properties) {
        this.properties.putAll(properties);
        this.suppressDate = StringUtility.isTrue(properties.getProperty("suppressDate"));
        this.suppressAllComments = StringUtility.isTrue(properties.getProperty("suppressAllComments"));
    }

    /**
     * 生成的实体类上添加注释
     *
     * @param topLevelClass
     * @param introspectedTable
     */
    @Override
    public void addModelClassComment(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        // 由于 Java 文件合并的困难,此方法的默认实现不应添加注释。仅当用户特别请求(例如,通过启用表备注注释)时,才应添加注释。
        if (this.suppressAllComments || this.suppressClassComments) {
            return;
        }

        StringBuilder sb = new StringBuilder();
        topLevelClass.addJavaDocLine("/**");
        sb.append(" * ");
        // 表注释
        sb.append(introspectedTable.getRemarks());
        sb.append("\n");
        sb.append(" * ");
        sb.append("\n");
        sb.append(" * @author ");
        sb.append(this.systemPro.getProperty("user.name"));
        if (!this.suppressDate) {
            sb.append("\n");
            sb.append(" * @date ");
            sb.append(getDateString());
        }

        sb.append("\n");
        sb.append(" */");
        topLevelClass.addJavaDocLine(sb.toString());
    }

    @Override
    public void addFieldComment(Field field, IntrospectedTable introspectedTable, IntrospectedColumn introspectedColumn) {
        if (this.suppressAllComments) {
            return;
        }

        StringBuilder sb = new StringBuilder();
        field.addJavaDocLine("/**");
        sb.append(" * ");
        sb.append(introspectedColumn.getRemarks());
        field.addJavaDocLine(sb.toString().replace("\n", " "));
        field.addJavaDocLine(" */");
    }

    @Override
    public void addFieldComment(Field field, IntrospectedTable introspectedTable) {
        if (this.suppressAllComments) {
            return;
        }

        StringBuilder sb = new StringBuilder();
        field.addJavaDocLine("/**");
        sb.append(" * ");
        sb.append(introspectedTable.getFullyQualifiedTable());
        field.addJavaDocLine(sb.toString().replace("\n", " "));
        field.addJavaDocLine(" */");
    }


    @Override
    public void addClassComment(InnerClass innerClass, IntrospectedTable introspectedTable, boolean markAsDoNotDelete) {
        if (this.suppressAllComments) {
            return;
        }

        StringBuilder sb = new StringBuilder();
        innerClass.addJavaDocLine("/**");
        sb.append(" * ");
        sb.append(introspectedTable.getFullyQualifiedTable());
        innerClass.addJavaDocLine(sb.toString());

        sb.setLength(0);
        sb.append(" * @author ");
        sb.append(this.systemPro.getProperty("user.name"));
        sb.append(" ");
        sb.append(getDateString());
        innerClass.addJavaDocLine(" */");
    }

    @Override
    public void addClassComment(InnerClass innerClass, IntrospectedTable introspectedTable) {
        if (this.suppressAllComments) {
            return;
        }

        StringBuilder sb = new StringBuilder();

        innerClass.addJavaDocLine("/**");
        sb.append(" * ");
        sb.append(introspectedTable.getFullyQualifiedTable());
        innerClass.addJavaDocLine(sb.toString());

        sb.setLength(0);
        sb.append(" * @author ");
        sb.append(systemPro.getProperty("user.name"));
        sb.append(" ");
        sb.append(getDateString());
        innerClass.addJavaDocLine(" */");
    }

    public void addEnumComment(InnerEnum innerEnum, IntrospectedTable introspectedTable) {
        if (this.suppressAllComments) {
            return;
        }

        StringBuilder sb = new StringBuilder();

        innerEnum.addJavaDocLine("/**");
        sb.append(" * ");
        sb.append(introspectedTable.getFullyQualifiedTable());
        innerEnum.addJavaDocLine(sb.toString());
        innerEnum.addJavaDocLine(" */");
    }

    @Override
    public void addGetterComment(Method method, IntrospectedTable introspectedTable, IntrospectedColumn introspectedColumn) {
        if (this.suppressAllComments) {
            return;
        }

        method.addJavaDocLine("/**");
        StringBuilder sb = new StringBuilder();
        sb.append(" * ");
        sb.append(introspectedColumn.getRemarks());
        sb.append("\n");
        sb.append(" * ");
        method.addJavaDocLine(sb.toString());
        sb.setLength(0);
        sb.append(" * @return ");
        sb.append(underlineToCamel(introspectedColumn.getActualColumnName()));
        sb.append(" ");
        sb.append(introspectedColumn.getRemarks());
        method.addJavaDocLine(sb.toString());
        method.addJavaDocLine(" */");
    }


    @Override
    public void addSetterComment(Method method, IntrospectedTable introspectedTable, IntrospectedColumn introspectedColumn) {
        if (this.suppressAllComments) {
            return;
        }

        method.addJavaDocLine("/**");
        StringBuilder sb = new StringBuilder();
        sb.append(" * ");
        sb.append(introspectedColumn.getRemarks());
        sb.append("\n");
        sb.append(" * ");
        method.addJavaDocLine(sb.toString());
        Parameter parm = (Parameter) method.getParameters().get(0);
        sb.setLength(0);
        sb.append(" * @param ");
        //setter方法参数名存在下划线,改为小驼峰
        sb.append(underlineToCamel(parm.getName()));
        sb.append(" ");
        sb.append(introspectedColumn.getRemarks());
        method.addJavaDocLine(sb.toString());
        method.addJavaDocLine(" */");
    }


    /**
     * 处理日期
     */
    protected String getDateString() {
        String result = null;
        if (!this.suppressDate) {
            result = this.currentDateStr;
        }
        return result;
    }

    /**
     * 下划线命名转为驼峰
     *
     * @param name 变量名
     */
    private String underlineToCamel(String name) {
        if (StringUtils.isBlank(name) || !name.contains("_")) {
            return name;
        }

        String result = "";
        String[] array = name.split("_");
        for (int i = 0; i < array.length; i++) {
            if (i == 0) {
                result += array[i];
            } else {
                result += StringUtils.capitalize(array[i]);
            }
        }
        return result;
    }
}

配置 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>
	<context id="mysqlTables" targetRuntime="MyBatis3">
		<!-- 指定生成的java文件的编码,没有直接生成到项目时中文可能会乱码 -->
		<property name="javaFileEncoding" value="UTF-8"/>

		<!-- 生成mapper.xml时覆盖原文件 -->
		<plugin type="org.mybatis.generator.plugins.UnmergeableXmlMappersPlugin" />
		<!-- 实体类使用lombok -->
		<plugin type="com.yl.ext.LomBokPlugin" >
			<property name="hasLombok" value="true" />
			<property name="user.name" value="liuxubo" />
			<property name="dateTimeFormat" value="yyyy/MM/dd HH:mm" />
		</plugin>

		<!-- 抑制生成注释,由于注释都是英文可以不生成  自定义中文注释生成-->
		<commentGenerator type="com.yl.ext.ZhCnCommentGenerator">
			<property name="suppressDate" value="true"/>
			<property name="suppressAllComments" value="true" />
		</commentGenerator>

		<!-- 1 jdbcConnection 配置数据库连接信息 -->
		<jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
			connectionURL="jdbc:mysql://localhost:3306/springboot?serverTimezone=Asia/Shanghai&amp;useUnicode=true&amp;characterEncoding=utf-8&amp;useSSL=false"
			userId="root" password="123456">
			<property name="nullCatalogMeansCurrent" value="true"/>
		</jdbcConnection>
		
		<!-- 默认false,把JDBC DECIMAL 和 NUMERIC 类型解析为 Integer,为 true时把JDBC DECIMAL 和 NUMERIC 类型解析为java.math.BigDecimal -->	
		<javaTypeResolver>
			<property name="forceBigDecimals" value="true" />
		</javaTypeResolver>	
			
		<!--2 javaModelGenerator 配置 JavaBean(实体类) 的⽣成策略。targetPackage:实体类所在的包 targetProject:创建包的位置 -->
		<javaModelGenerator targetPackage="com.yl.entity" targetProject="./src/main/java">
			<!-- enableSubPackages:是否让schema作为包的后缀 -->
			<property name="enableSubPackages" value="false" />
			<!-- 从数据库返回的值清理前后的空格 -->
			<property name="trimStrings" value="true" />
		</javaModelGenerator>
		
		<!--3 生成DAO的包名和位置 -->
		<sqlMapGenerator targetPackage="com.yl.dao" targetProject="./src/main/java">
			<!-- enableSubPackages:是否让schema作为包的后缀 -->
			<property name="enableSubPackages" value="false" />	
		</sqlMapGenerator>

		<!--4 生成xml映射文件 ANNOTATEDMAPPER注解方式,MAPPER或者XMLMAPPER XML方式 -->
		<javaClientGenerator type="XMLMAPPER" targetPackage="com.yl.dao" targetProject="./src/main/java">
			<!-- enableSubPackages:是否让schema作为包的后缀 -->
			<property name="enableSubPackages" value="false" />	
		</javaClientGenerator>
		
		<!--5 table 配置⽬标数据表(tableName:表名,domainObjectName:JavaBean 类名)默认生成Example类,添加属性可不生成 -->
		<table tableName="common_approve_log" domainObjectName="ApproveLog"
			modelType="flat"
			enableCountByExample="false"
	        enableUpdateByExample="false"
	        enableDeleteByExample="false" 
	        enableSelectByExample="false" 
	        selectByExampleQueryId="false" />

	        <!-- 可指定多个表 -->
	     <!-- <table tableName="proc_approve_log" domainObjectName="ApproveLog"  />   --> 
	        
	</context>
</generatorConfiguration>


测试类 生成 entity 含有 getter/setter方法

public class Main {
	/**
	 * mybatis-generator配置文件
	*/
	private static final String GENERATOR_CONFIG = "generatorConfig.xml";
	public static void main(String[] args) throws Exception{
		List<String> warings = new ArrayList<>();
		boolean overwrite = true;
		File configFile = new File(Thread.currentThread().getContextClassLoader().getResource(GENERATOR_CONFIG).getFile());
		
		ConfigurationParser configurationParser = new ConfigurationParser(warings);
		Configuration configuration = configurationParser.parseConfiguration(configFile);
		DefaultShellCallback callback = new DefaultShellCallback(overwrite);
		MyBatisGenerator myBatisGenerator = new MyBatisGenerator(configuration, callback, warings);
		myBatisGenerator.generate(null);
	}
}
方法2. 自定义实现PluginAdapter
package com.yl.ext;

import org.apache.commons.lang3.time.DateFormatUtils;
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.*;
import org.mybatis.generator.internal.util.StringUtility;

import java.util.Date;
import java.util.List;

/**
 * mybatis-generator实体类上lombok注释插件
 *
 * <p>在contex标签内添加
 * <pre>
 *    &lt;plugin type="com.yl.ext.LomBokPlugin" &gt;
 *       &lt;property name="hasLombok" value="true"/&gt;
 *       &lt;property name="user.name" value="liuxubo"/&gt;
 *       &lt;property name="dateTimeFormat" value="yyyy/MM/dd HH:mm"/&gt;
 *    &lt;/plugin&gt;
 *
 *      必须配置 suppressAllComments 为 true 否则 会重复生成注释
 *      &lt;commentGenerator type="com.yl.ext.ZhCnCommentGenerator"&gt;
 *         &lt;property name="suppressAllComments" value="true" /&gt;
 *       &lt;/commentGenerator&gt;
 *  </pre>
 *
 * @author buyl
 * @date 2019年5月30日 上午22:04:55
 */
public class LomBokPlugin extends PluginAdapter {

    @Override
    public boolean validate(List<String> list) {
        return true;
    }

    @Override
    public boolean modelBaseRecordClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        boolean hasLombok = Boolean.parseBoolean(properties.getProperty("hasLombok", "false"));
        if (hasLombok) {
            // 添加domain的import
            topLevelClass.addImportedType("lombok.Data");

            // 添加domain的注解
            topLevelClass.addAnnotation("@Data");
        }

        topLevelClass.addJavaDocLine("/**");

        String remarks = introspectedTable.getRemarks();
        if (StringUtility.stringHasValue(remarks)) {
            String[] remarkLines = remarks.split(System.getProperty("line.separator"));
            for (String remarkLine : remarkLines) {
                topLevelClass.addJavaDocLine(" * " + remarkLine);
            }
        }

        StringBuilder sb = new StringBuilder();
//        sb.append(" * ").append(introspectedTable.getFullyQualifiedTable());
        sb.append(" * ");
        topLevelClass.addJavaDocLine(sb.toString());
        sb.setLength(0);
        sb.append(" * @author ").append(properties.getProperty("user.name"));
        topLevelClass.addJavaDocLine(sb.toString());
        sb.setLength(0);
        sb.append(" * @date ");
        sb.append(getDateString());
        topLevelClass.addJavaDocLine(sb.toString());
        topLevelClass.addJavaDocLine(" */");
        return true;
    }

    @Override
    public boolean modelFieldGenerated(Field field, TopLevelClass topLevelClass, IntrospectedColumn introspectedColumn,
                                       IntrospectedTable introspectedTable, ModelClassType modelClassType) {
        field.addJavaDocLine("/**");
        String remarks = introspectedColumn.getRemarks();
        if (StringUtility.stringHasValue(remarks)) {
            String[] remarkLines = remarks.split(System.getProperty("line.separator"));
            for (String remarkLine : remarkLines) {
                field.addJavaDocLine(" * " + remarkLine);
            }
        }
        field.addJavaDocLine(" */");
        return true;
    }

    /**
     * 生成 Mapper接口
     *
     * @param interfaze
     * @param introspectedTable
     * @return:boolean
     */
    @Override
    public boolean clientGenerated(Interface interfaze, IntrospectedTable introspectedTable) {
        // 添加Mapper的import
        interfaze.addImportedType(new FullyQualifiedJavaType("org.apache.ibatis.annotations.Mapper"));

        //添加Mapper接口注释
        interfaze.addJavaDocLine("/**");
        interfaze.addJavaDocLine(" * " + introspectedTable.getRemarks());

        StringBuilder sb = new StringBuilder();
        sb.append(" * ");
        interfaze.addJavaDocLine(sb.toString());
        sb.setLength(0);
        sb.append(" * @author ").append(properties.getProperty("user.name"));
        interfaze.addJavaDocLine(sb.toString());
        sb.setLength(0);
        sb.append(" * @date ");
        sb.append(getDateString());
        interfaze.addJavaDocLine(sb.toString());
        interfaze.addJavaDocLine(" */");

        // 添加Mapper的注解
        interfaze.addAnnotation("@Mapper");
        return true;
    }


    /**
     * 生成setter方法
     *
     * @param method
     * @param topLevelClass
     * @param introspectedColumn
     * @param introspectedTable
     * @param modelClassType
     * @return:boolean
     */
    @Override
    public boolean modelSetterMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedColumn introspectedColumn,
                                              IntrospectedTable introspectedTable, ModelClassType modelClassType) {
        // 不生成getter
        boolean hasLombok = Boolean.parseBoolean(properties.getProperty("hasLombok", "false"));
        return !hasLombok;
    }

    /**
     * 生成getter方法
     *
     * @param method
     * @param topLevelClass
     * @param introspectedColumn
     * @param introspectedTable
     * @return:boolean
     */
    @Override
    public boolean modelGetterMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedColumn introspectedColumn,
                                              IntrospectedTable introspectedTable, ModelClassType modelClassType) {
        // 不生成setter
        boolean hasLombok = Boolean.parseBoolean(properties.getProperty("hasLombok", "false"));
        return !hasLombok;
    }

    protected String getDateString() {
        return DateFormatUtils.format(new Date(), properties.getProperty("dateTimeFormat", "yyyy-MM-dd HH:mm:ss"));
    }
}

方法3. 脚本方式

将mybatis-geerator 项目 执行 mvn clean package 打包
在mybatis-geerator.jar 目录下 新建脚本 install.bat

echo off
::set JAVA_HOME=C:\Program Files\Java\jdk1.8.0_251
::set M2_HOME=D:\workProgram\apache-maven-3.6.3
 
::set PATHP=%PATH%
::set PATH=%PATH%;%M2_HOME%\bin;%ANT_HOME%\bin
 
java -jar mybatis-geerator-1.0.0.jar -configfile generatorConfig.xml -overwrite
 
::set PATHP=%PATH%

mybatis-geerator.jar包内 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>
	<context id="mysqlTables" targetRuntime="MyBatis3">
		<!-- 指定生成的java文件的编码,没有直接生成到项目时中文可能会乱码 -->
		<property name="javaFileEncoding" value="UTF-8"/>

		<!-- 生成mapper.xml时覆盖原文件 -->
		<plugin type="org.mybatis.generator.plugins.UnmergeableXmlMappersPlugin" />

			<!-- 实体类使用lombok -->
		<plugin type="com.yl.ext.LomBokPlugin" >
			<property name="hasLombok" value="true" />
			<property name="user.name" value="liuxubo" />
			<property name="dateTimeFormat" value="yyyy/MM/dd HH:mm" />
		</plugin>

		<!-- 抑制生成注释,由于注释都是英文可以不生成  自定义主中文注释生成-->
		<commentGenerator type="com.yl.ext.ZhCnCommentGenerator">
			<property name="suppressDate" value="true"/>
			<property name="suppressAllComments" value="true" />
		</commentGenerator>

		<!-- 1 jdbcConnection 配置数据库连接信息。 -->
		<jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
			connectionURL="jdbc:mysql://localhost:3306/activiti5?serverTimezone=Asia/Shanghai&amp;useUnicode=true&amp;characterEncoding=utf-8&amp;useSSL=false"
			userId="root" password="123456">
		</jdbcConnection>
		
		<!-- 默认false,把JDBC DECIMAL 和 NUMERIC 类型解析为 Integer,为 true时把JDBC DECIMAL 和 NUMERIC 类型解析为java.math.BigDecimal -->	
		<javaTypeResolver>
			<property name="forceBigDecimals" value="true" />
		</javaTypeResolver>	
			
		<!--2 javaModelGenerator 配置 JavaBean(实体类) 的⽣成策略。targetPackage:实体类所在的包 targetProject:创建包的位置 -->
		<javaModelGenerator targetPackage="com.yl.entity" targetProject="./">
			<!-- enableSubPackages:是否让schema作为包的后缀 -->
			<property name="enableSubPackages" value="false" />
			<!-- 从数据库返回的值清理前后的空格 -->
			<property name="trimStrings" value="true" />
		</javaModelGenerator>
		
		<!--3 生成DAO的包名和位置 -->
		<sqlMapGenerator targetPackage="com.yl.dao" targetProject="./">
			<!-- enableSubPackages:是否让schema作为包的后缀 -->
			<property name="enableSubPackages" value="false" />	
		</sqlMapGenerator>
		
		<!--4 生成xml映射文件 ANNOTATEDMAPPER注解方式,MAPPER或者XMLMAPPER XML方式 -->
		<javaClientGenerator type="XMLMAPPER" targetPackage="com.yl.dao" targetProject="./">
			<!-- enableSubPackages:是否让schema作为包的后缀 -->
			<property name="enableSubPackages" value="false" />	
		</javaClientGenerator>
		
		<!--5 table 配置⽬标数据表(tableName:表名,domainObjectName:JavaBean 类名)默认生成Example类,添加属性可不生成 -->
		<table tableName="proc_approve_log" domainObjectName="ApproveLog"
			modelType="flat"
			enableCountByExample="false"
	        enableUpdateByExample="false"
	        enableDeleteByExample="false" 
	        enableSelectByExample="false" 
	        selectByExampleQueryId="false" />
	        
	        <!-- 可指定多个表 -->
	     <!-- <table tableName="proc_approve_log" domainObjectName="ApproveLog"  />   --> 
	        
	</context>
</generatorConfiguration>

直接执行 install.bat 可在当前目录下生成代码

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值