mybatis generator自定义model的代码注释

news2025/2/28 2:56:23

mbg相信大家都比较熟悉,可以自动化的生成数据库表对应的model,mapper。但是最近在使用mbg的时候遇到了这样的问题:

1、生成的model虽然可以根据数据库字段的comment生成注释,但这些注释仅对后端开发人员可见,如果想让前端人员通过swagger查看,仍需要手动添加注解,比如@ApiModelProperty;

2、手动添加@ApiModelProperty注解之后,如果数据库表有修改,当使用mbg重新生成之后,之前手工添加的@ApiModelProperty会被覆盖,又得重新添加。

针对以上问题,mybatis提供了解决方案,就是CommentGenerator,下面介绍下CommentGenerator的用法。

项目结构如下。

 首先generator.properties文件中存放了数据库连接信息,类似这种:

jdbc.driverClass=com.mysql.cj.jdbc.Driver
jdbc.connectionURL=jdbc:mysql://localhost:3306/mysql?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&useSSL=false
jdbc.userId=
jdbc.password=

然后看一下generatorConfig.xml文件。特别注意CommentGenerator标签指向的就是今天的主角。

<?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>
    <properties resource="generator.properties"/>
    <context id="MySqlContext" targetRuntime="MyBatis3" defaultModelType="flat">
        <property name="beginningDelimiter" value="`"/>
        <property name="endingDelimiter" value="`"/>
        <property name="javaFileEncoding" value="UTF-8"/>
        <!-- 为模型生成序列化方法-->
        <plugin type="org.mybatis.generator.plugins.SerializablePlugin"/>
        <!-- 为生成的Java模型创建一个toString方法 -->
        <plugin type="org.mybatis.generator.plugins.ToStringPlugin"/>
        <!--生成mapper.xml时覆盖原文件-->
        <plugin type="org.mybatis.generator.plugins.UnmergeableXmlMappersPlugin" />
        <commentGenerator type="com.useless.matrix.data.CommentGenerator">
            <!-- 是否去除自动生成的注释 true:是 : false:否 -->
            <property name="suppressAllComments" value="true"/>
            <property name="suppressDate" value="true"/>
            <property name="addRemarkComments" value="true"/>
        </commentGenerator>

        <jdbcConnection driverClass="${jdbc.driverClass}"
                        connectionURL="${jdbc.connectionURL}"
                        userId="${jdbc.userId}"
                        password="${jdbc.password}">
            <!--解决mysql驱动升级到8.0后不生成指定数据库代码的问题-->
            <property name="nullCatalogMeansCurrent" value="true" />
        </jdbcConnection>

        <javaModelGenerator targetPackage="com.useless.matrix.data.mbg.model" targetProject="matrix-data/src/main/java"/>

        <sqlMapGenerator targetPackage="com.useless.matrix.data.mbg.mapper" targetProject="matrix-data/src/main/resources"/>

        <javaClientGenerator type="XMLMAPPER" targetPackage="com.useless.matrix.data.mbg.mapper"
                             targetProject="matrix-data/src/main/java"/>
        <!--生成全部表tableName设为%-->
        <table tableName="account">
            <generatedKey column="id" sqlStatement="MySql" identity="true"/>
        </table>
    </context>
</generatorConfiguration>

Generator类的main方法会读取generatorConfig.xml,生成model和mapper:

package com.useless.matrix.data;

import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.config.Configuration;
import org.mybatis.generator.config.xml.ConfigurationParser;
import org.mybatis.generator.internal.DefaultShellCallback;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;


public class Generator {
    public static void main(String[] args) throws Exception {
        //MBG 执行过程中的警告信息
        List<String> warnings = new ArrayList<String>();
        //当生成的代码重复时,覆盖原代码
        boolean overwrite = true;
        //读取我们的 MBG 配置文件
        InputStream is = Generator.class.getResourceAsStream("/generatorConfig.xml");
        ConfigurationParser cp = new ConfigurationParser(warnings);
        Configuration config = cp.parseConfiguration(is);
        is.close();

        DefaultShellCallback callback = new DefaultShellCallback(overwrite);
        //创建 MBG
        MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
        //执行生成代码
        myBatisGenerator.generate(null);
        //输出警告信息
        for (String warning : warnings) {
            System.out.println(warning);
        }
    }
}

下面有请主角CommentGenerator类:

package com.useless.matrix.data;

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.FullyQualifiedJavaType;
import org.mybatis.generator.internal.DefaultCommentGenerator;
import org.mybatis.generator.internal.util.StringUtility;

import java.util.Properties;

/**
 * 自定义注释生成器
 */
public class CommentGenerator extends DefaultCommentGenerator {
    private boolean addRemarkComments = false;
    private static final String EXAMPLE_SUFFIX="Example";
    private static final String MAPPER_SUFFIX="Mapper";
    private static final String API_MODEL_PROPERTY_FULL_CLASS_NAME="io.swagger.annotations.ApiModelProperty";
    private static final String JSON_FORMAT="com.fasterxml.jackson.annotation.JsonFormat";
    /**
     * 设置用户配置的参数
     */
    @Override
    public void addConfigurationProperties(Properties properties) {
        super.addConfigurationProperties(properties);
        this.addRemarkComments = StringUtility.isTrue(properties.getProperty("addRemarkComments"));
    }

    /**
     * 给字段添加注释
     */
    @Override
    public void addFieldComment(Field field, IntrospectedTable introspectedTable,
                                IntrospectedColumn introspectedColumn) {
        String remarks = introspectedColumn.getRemarks();
        //根据参数和备注信息判断是否添加swagger注解信息
        if(addRemarkComments&&StringUtility.stringHasValue(remarks)){
//            addFieldJavaDoc(field, remarks);
            //数据库中特殊字符需要转义
            if(remarks.contains("\"")){
                remarks = remarks.replace("\"","'");
            }
            //A 给model的字段添加swagger注解
            field.addJavaDocLine("@ApiModelProperty(value = \""+remarks+"\")");
            System.out.println(field.getType());

        }

        //B 给时间字段规定格式
        if (field.getType().equals(FullyQualifiedJavaType.getDateInstance())) {
            field.addJavaDocLine("@JsonFormat(pattern = \"yyyy-MM-dd HH:mm:ss\",timezone = \"GMT+8\")");
        }
    }

    /**
     * 给model的字段添加注释
     */
    private void addFieldJavaDoc(Field field, String remarks) {
        //文档注释开始
        field.addJavaDocLine("/**");
        //获取数据库字段的备注信息
        String[] remarkLines = remarks.split(System.getProperty("line.separator"));
        for(String remarkLine:remarkLines){
            field.addJavaDocLine(" * "+remarkLine);
        }
        addJavadocTag(field, false);
        field.addJavaDocLine(" */");
    }

    @Override
    public void addJavaFileComment(CompilationUnit compilationUnit) {
        super.addJavaFileComment(compilationUnit);
        //只在model中添加swagger注解类的导入
        if(!compilationUnit.getType().getFullyQualifiedName().contains(MAPPER_SUFFIX)&&!compilationUnit.getType().getFullyQualifiedName().contains(EXAMPLE_SUFFIX)){
            compilationUnit.addImportedType(new FullyQualifiedJavaType(API_MODEL_PROPERTY_FULL_CLASS_NAME));
            compilationUnit.addImportedType(new FullyQualifiedJavaType(JSON_FORMAT));
        }
    }
}

注意到45行A处的代码,其实就是根据remark为生成的model加一行@ApiModelProperty代码。

51行B处的代码是为数据库中的Date格式的字段添加一行@JsonFormat代码,指定统一的格式。

这样还不够,我们还需要手动地添加注解对应的import,注意看addJavaFileComment方法:

 现在运行generator类的main方法,查看model,发现已经正确生成并添加了注解:

 每次使用mbg生成model都会自动添加注解,实在是太方便啦。

具体代码请移步gitee https://gitee.com/lisz112/matrix.git。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/468433.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

HNU-计算机系统-实验3-BombLab

写在前面 首先要感谢A橙_大佬&#xff0c;在之前的实验以及学习中&#xff0c;许多地方参考与学习了大佬的思路。 本次实验也是听取了A橙_大佬的建议&#xff0c;先自己做一遍&#xff0c;再看答案&#xff0c;有了更进一步的深入理解。 最后在验收的时候&#xff0c;发现验…

“豪”秀上演——莱佛士学生作品精彩亮相施华蔻发布会

4月12日&#xff0c;一场美轮美奂的视觉盛宴——施华蔻专业2023春夏新季风发布会&#xff0c;在广州珠江琶醍啤酒文化创意艺术区盛大举行。 ▲施华蔻专业2023春夏新季风发布会现场 当天发布会以《重组新生》为主题&#xff0c;施华蔻将潮流趋势、前沿发艺与先锋科技相结合&…

c++中set_difference这个函数的意义和用法

今天正好碰到了这个函数&#xff0c;虽然大概可以猜出这个函数的作用&#xff0c;但是仍然期待一个通俗易懂的解释&#xff0c;网上搜索了一下&#xff0c;搜到百度百科&#xff0c;感觉没有抓住重点&#xff0c;虽然示例也勉强可以理解&#xff0c;但是总感觉讲究不够直观。 …

【PLC】贝加莱PLC理论及实操年度培训

最近在进行PLC培训&#xff0c;主要是贝加莱PLC产品的学习&#xff0c;学习了上下位机的一些基本操作&#xff0c;能够进行一些简单的实践&#xff0c;最后顺利通过年度考核。 0 引言 PLC&#xff1a;可编程逻辑控制器&#xff0c;由CPU、存储器、输入输出接口、电影以及外部设…

冬奥会传统文化管理系统【GUI/Swing+MySQL】(Java课设)

系统类型 Swing窗口类型Mysql数据库存储数据 使用范围 适合作为Java课设&#xff01;&#xff01;&#xff01; 部署环境 jdk1.8Mysql8.0Idea或eclipsejdbc 运行效果 本系统源码地址&#xff1a;https://download.csdn.net/download/qq_50954361/87720226 更多系统资源库…

Access Token 访问令牌 的获取与使用

一、引用 三方库导入时&#xff0c;通常需要输入账号和令牌进行鉴权。账号为指定平台的 HTTP 克隆账号&#xff0c;访问令牌即 Access Token&#xff0c;本文介绍如何获取常见三方代码平台的Access Token。 Access Token 通常在代码平台的个人账号设置内进行管理和配置&#xf…

C++ 树进阶系列之探讨深度搜索算法查找环的细枝末节

1. 前言 对于基环树的讲解&#xff0c;分上、下 2 篇&#xff0c;上篇以理解连通分量、环以及使用深度搜索算法检查连通性和环为主&#xff0c;下篇以基于基环树结构的应用为主。 什么是基环树&#xff1f; 所谓基环树指由n个节点n条边所构建而成的连通图。 如下图所示&…

[Java 数据结构] 反射、枚举和lambda表达式

&#x1f389;&#x1f389;&#x1f389;点进来你就是我的人了 博主主页&#xff1a;&#x1f648;&#x1f648;&#x1f648;戳一戳,欢迎大佬指点!人生格言&#xff1a;当你的才华撑不起你的野心的时候,你就应该静下心来学习! 欢迎志同道合的朋友一起加油喔&#x1f9be;&am…

集成学习随机森林

集成学习 集成学习分为三类算法&#xff1a; 装袋法&#xff08;Bagging&#xff09;&#xff0c;提升法&#xff08;Boosting&#xff09;和融合stacking。 Bagging&#xff1a;核心思想是构建多个相互独立的评估器&#xff0c;然后对其预测进行平均或多数表决原则来决定集成…

极客星球|数据分析引擎黑马ClickHouse技术研究与实践

ClickHouse 在近几年是大数据分析引擎界的一匹黑马&#xff0c;从默默无闻到一路起飞&#xff0c;在 DB engine Rank 上进入前50名&#xff0c;成为全球数据引擎界耀眼的一颗明星。在全球范围内&#xff0c;ClickHouse 单表查询比其他引擎要快数倍以上&#xff0c;在过去的几年…

Vue+Echart实现利用率表盘效果【组件已封装,可直接使用】

效果演示 当利用超过70%&#xff08;可以自行设置&#xff09;&#xff0c;表盘变红 组件 里面对应两个图片资源&#xff0c;panelBackground_red.png 和 panelBackground_green.png&#xff0c;请前往百度网盘进行下载。如果喜欢其他颜色&#xff0c;可以使用.psd来修改导出…

redis从头开始【一】--面试的小伙伴必看

一 什么是NoSQL&#xff1f; Nosql not only sql&#xff08;不仅仅是SQL&#xff09; 关系型数据库&#xff1a;列行&#xff0c;同一个表下数据的结构是一样的。 非关系型数据库&#xff1a;数据存储没有固定的格式&#xff0c;并且可以进行横向扩展。 NoSQL泛指非关系型…

10.Yarn概述

如果说HDFS是存储&#xff0c;则Yarn就是cpu和内存&#xff0c;mapreduce就是程序。 1.基础架构 复习&#xff1a; 1.Container就是一个容器&#xff0c;其中封装了需要使用的内存与cpu 2.每当提交一个job,就会产生一个appMaster(总指挥),app Master负责其他container里面的…

【分布式技术专题】「分布式技术架构」手把手教你如何开发一个属于自己的Redis延时队列的功能组件

手把手教你如何开发一个属于自己的延时队列的功能组件 前提介绍解决痛点延时队列组件的架构延时队列组件的初始化流程延时队列组件的整体核心类架构延时队列组件的整体核心类功能 延时队列的开发组件延迟队列的机制配置初始化类源码 - DelayedQueueConfigurationRedission客户端…

排序算法 - 冒泡排序

文章目录 冒泡排序介绍冒泡排序实现复杂度和稳定性冒泡排序时间复杂度冒泡排序稳定性 代码实现核心&注意结尾 每日一道算法提高脑力&#xff0c;今天是第一天&#xff0c;来个最简单的算法–冒泡排序。 冒泡排序介绍 它是一种较简单的排序算法。它会遍历若干次要排序的数列…

jQuery知识点一

一、 jQuery 介绍 1.jQuery的概念&#xff1a; jQuery 是一个快速、简洁的 JavaScript 库&#xff0c;其设计的宗旨是“write Less&#xff0c;Do More”&#xff0c;即倡导写更少的代码&#xff0c;做更多的事情。 j 就是 JavaScript&#xff1b; Query 查询&#xff1b; 意思…

学习 Python 之 Pygame 开发魂斗罗(十五)

学习 Python 之 Pygame 开发魂斗罗&#xff08;十五&#xff09; 给魂斗罗游戏加入Boss1. 分析boss2. 创建boss类3. 在主类中加载Boss4. 修改子弹类逻辑&#xff0c;让boss可以开火5. 修改主类逻辑&#xff0c;让boss正常开火 给魂斗罗游戏加入Boss 在上次的博客学习 Python 之…

如何在不重装系统的情况下换固态硬盘?

随着固态硬盘的价格不断下降&#xff0c;越来越多的计算机用户希望用固态硬盘替换老旧的机械硬盘以获得更好的性能。 但是常规方法就避免不了重装系统&#xff0c;用户配置文件、系统设置、个人文件和已安装的程序又需要重新配置一遍。此外&#xff0c;还可能重新遇到很多问题…

城市“一网统管”平台—智慧平安小区的场景应用

随着城市建设进程的不断加快&#xff0c;关于城市的智能化治理需求也随之增多。在国家发布的“十四五”规划中&#xff0c;已经明确指出&#xff0c;推进新型城市建设&#xff0c;推行城市运行一网统管。作为推动城市治理体系和治理能力现代化的重要探索&#xff0c;“一网统管…

Linux/Unix常见IO模型

阻塞&#xff08;Blocking I/O&#xff09;、非阻塞&#xff08;Non-Blocking I/O&#xff09;、IO多路复用&#xff08;I/O Multiplexing&#xff09;、 信号驱动 I/O&#xff08;Signal Driven I/O&#xff09;&#xff08;不常用&#xff09;和异步&#xff08;Asynchronous…