9.基于SpringBoot3+MybatisPlus定制化代码生成器类

我们在3.基于SpringBoot3集成MybatisPlus中讲到自定义代码生成器,但是往往遗留代码生成的类格式或者命名不符合要求,需要手工修改,但是当表很多时就比较头痛,所以我们自定义模板在进行代码生成

1. 新建MyTemplateEngine.java类

里面大多实现直接拷贝自VelocityTemplateEngine.java, 只是增加了反射,修改包名,搜索修改地方即可找到两处位置

public class MyTemplateEngine extends AbstractTemplateEngine {

    /**
     * 批量输出 java xml 文件
     */
    @NotNull
    public AbstractTemplateEngine batchOutput() {
        try {
            ConfigBuilder config = this.getConfigBuilder();
            List<TableInfo> tableInfoList = config.getTableInfoList();
            tableInfoList.forEach(tableInfo -> {
                Map<String, Object> objectMap = this.getObjectMap(config, tableInfo);
                // 修改地方一:通过反射修改属性值,替换不需要的前缀
                Class<? extends  TableInfo> clazz = tableInfo.getClass();
                try {
                    Field name = clazz.getDeclaredField("name");
                    name.setAccessible(true);
                    name.set(tableInfo, tableInfo.getName().replaceFirst("tb_", ""));

                    Field entityName = clazz.getDeclaredField("entityName");
                    entityName.setAccessible(true);
                    entityName.set(tableInfo, tableInfo.getEntityName().replaceFirst("Tb", ""));

                    Field mapperName = clazz.getDeclaredField("mapperName");
                    mapperName.setAccessible(true);
                    mapperName.set(tableInfo, tableInfo.getMapperName().replaceFirst("Tb", ""));

                    Field xmlName = clazz.getDeclaredField("xmlName");
                    xmlName.setAccessible(true);
                    xmlName.set(tableInfo, tableInfo.getXmlName().replaceFirst("Tb", ""));

                    Field serviceName = clazz.getDeclaredField("serviceName");
                    serviceName.setAccessible(true);
                    serviceName.set(tableInfo, tableInfo.getServiceName().replaceFirst("ITb", ""));

                    Field serviceImplName = clazz.getDeclaredField("serviceImplName");
                    serviceImplName.setAccessible(true);
                    serviceImplName.set(tableInfo, tableInfo.getServiceImplName().replaceFirst("Tb", ""));

                    Field controllerName = clazz.getDeclaredField("controllerName");
                    controllerName.setAccessible(true);
                    controllerName.set(tableInfo, tableInfo.getControllerName().replaceFirst("Tb", ""));
                } catch (NoSuchFieldException e) {
                    throw new RuntimeException(e);
                } catch (IllegalAccessException e) {
                    throw new RuntimeException(e);
                }
                Optional.ofNullable(config.getInjectionConfig()).ifPresent(t -> {
                    // 添加自定义属性
                    t.beforeOutputFile(tableInfo, objectMap);
                    // 输出自定义文件
                    outputCustomFile(t.getCustomFiles(), tableInfo, objectMap);
                });
		// 修改地方二
                objectMap.put("entity", String.valueOf(objectMap.get("entity")).replaceFirst("Tb", ""));
                // entity
                outputEntity(tableInfo, objectMap);
                // mapper and xml
                outputMapper(tableInfo, objectMap);
                // service
                outputService(tableInfo, objectMap);
                // controller
                outputController(tableInfo, objectMap);
            });
        } catch (Exception e) {
            throw new RuntimeException("无法创建文件,请检查配置信息!", e);
        }
        return this;
    }

    private VelocityEngine velocityEngine;

    {
        try {
            Class.forName("org.apache.velocity.util.DuckType");
        } catch (ClassNotFoundException e) {
            // velocity1.x的生成格式错乱 https://github.com/baomidou/generator/issues/5
            LOGGER.warn("Velocity 1.x is outdated, please upgrade to 2.x or later.");
        }
    }

    @Override
    public @NotNull MyTemplateEngine init(@NotNull ConfigBuilder configBuilder) {
        if (null == velocityEngine) {
            Properties p = new Properties();
            p.setProperty(ConstVal.VM_LOAD_PATH_KEY, ConstVal.VM_LOAD_PATH_VALUE);
            p.setProperty(Velocity.FILE_RESOURCE_LOADER_PATH, StringPool.EMPTY);
            p.setProperty(Velocity.ENCODING_DEFAULT, ConstVal.UTF8);
            p.setProperty(Velocity.INPUT_ENCODING, ConstVal.UTF8);
            p.setProperty("file.resource.loader.unicode", StringPool.TRUE);
            velocityEngine = new VelocityEngine(p);
        }
        return this;
    }


    @Override
    public void writer(@NotNull Map<String, Object> objectMap, @NotNull String templatePath, @NotNull File outputFile) throws Exception {
        Template template = velocityEngine.getTemplate(templatePath, ConstVal.UTF8);
        try (FileOutputStream fos = new FileOutputStream(outputFile);
             OutputStreamWriter ow = new OutputStreamWriter(fos, ConstVal.UTF8);
             BufferedWriter writer = new BufferedWriter(ow)) {
            template.merge(new VelocityContext(objectMap), writer);
        }
        LOGGER.debug("模板:" + templatePath + ";  文件:" + outputFile);
    }


    @Override
    public @NotNull String templateFilePath(@NotNull String filePath) {
        final String dotVm = ".vm";
        return filePath.endsWith(dotVm) ? filePath : filePath + dotVm;
    }
}
2. 模板文件替换修改

IDEA全局搜索需要的下图文件,拷贝至resources/templates下,然后把里面的内容根据自己需求进行模板调整

3. 代码生成类

之前是Swagger注解,我们调整为Springdoc注解,并对实体不额外添加后缀%s

public class FastAutoGeneratorTest {
    public static void main(String[] args) {
        DataSourceConfig.Builder dataSourceConfig = new DataSourceConfig.Builder("jdbc:mysql://XXXX:3306/yy_dev?useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&autoReconnect=true&failOverReadOnly=false&allowMultiQueries=true&serverTimezone=Asia/Shanghai","root","Gensci@123");
        FastAutoGenerator.create(dataSourceConfig)
                // 全局配置
                .globalConfig((scanner, builder) -> builder.enableSpringdoc().author(scanner.apply("请输入作者名称?")))
                // 包配置
                .packageConfig((scanner, builder) -> builder.parent(scanner.apply("请输入包名?")))
                // 策略配置
                .templateEngine(new MyTemplateEngine())
                .strategyConfig((scanner, builder) -> builder.addInclude(getTables(scanner.apply("请输入表名,多个英文逗号分隔?所有输入 all")))
                        .controllerBuilder().enableRestStyle().enableHyphenStyle()
                        .entityBuilder().enableLombok().enableTableFieldAnnotation().idType(IdType.INPUT).formatFileName("%s").build())
                .execute();
    }

    // 处理 all 情况
    protected static List<String> getTables(String tables) {
        return "all".equals(tables) ? Collections.emptyList() : Arrays.asList(tables.split(","));
    }
}
4. 效果如图

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

小型心仪什么牌子好又便宜?迷你洗衣机品牌推荐

相信不少人群为了方便清洗衣服&#xff0c;都会直接选择了大型的洗衣机。由于家里住的人多&#xff0c;所以对洗衣机的使用还是比较频繁&#xff0c;但内衣裤和其它衣服混合在一起清洗的话&#xff0c;或许大多数人都不太会接受的了&#xff0c;所以都是选择自己手工洗的&#…

【uniapp/uview1.x】u-upload 在 v-for 中的使用时, before-upload 如何传参

引入&#xff1a; 是这样一种情况&#xff0c;在接口获取数据之后&#xff0c;是一个数组列表&#xff0c;循环展示后&#xff0c;需要在每条数据中都要有图片上传&#xff0c;互不干扰。 分析&#xff1a; uview 官网中有说明&#xff0c;before-upload 是不加括号的&#xff…

springboot服务和python服务如何自定义启动banner

shigen日更文章的博客写手&#xff0c;擅长Java、python、vue、shell等编程语言和各种应用程序、脚本的开发。记录成长&#xff0c;分享认知&#xff0c;留住感动。 shigen最近在修改ruoyi的框架&#xff0c;看到了框架自带的banner图&#xff0c;就是一个不爽&#xff0c;于是…

AI大模型低成本快速定制法宝:RAG和向量数据库

文章目录 1. 前言2. RAG和向量数据库3. 论坛日程4. 购票方式 1. 前言 当今人工智能领域&#xff0c;最受关注的毋庸置疑是大模型。然而&#xff0c;高昂的训练成本、漫长的训练时间等都成为了制约大多数企业入局大模型的关键瓶颈。 这种背景下&#xff0c;向量数据库凭借其独特…

3.5 Windows驱动开发:应用层与内核层内存映射

在上一篇博文《内核通过PEB得到进程参数》中我们通过使用KeStackAttachProcess附加进程的方式得到了该进程的PEB结构信息&#xff0c;本篇文章同样需要使用进程附加功能&#xff0c;但这次我们将实现一个更加有趣的功能&#xff0c;在某些情况下应用层与内核层需要共享一片内存…

freertos源码下载和目录结构分析

1、源码下载 下载网址&#xff1a;https://www.freertos.org/zh-cn-cmn-s/&#xff1b; 2、源码目录结构 3、关键的代码文件

全国行政区划2023年最新版

全国行政区划包含以下字段&#xff0c;行政区划第五级&#xff0c;省、市、县、乡镇、村。文章末尾已整理成sql文件。 父级行政代码,行政代码,邮政编码,区号,名称,简称,组合名,拼音,经度,纬度, 获取方式 关键词“行政区划”获取文件。 免费获取行政区划

我们常说的网络资产,具体是如何定义的?

文章目录 什么叫网络资产&#xff1f;官方定义的网络资产网络资产数字化定义推荐阅读 什么叫网络资产&#xff1f; 通过百度查询搜索什么叫网络资产&#xff1f;大体上都将网络资产归类为计算机网络中的各类设备。 基本上会定义网络传输通信架构中用到的主机、网络设备、防火…

通过注释来埋点

目录 开始 插件编写 功能一 功能二 功能三 合并功能 运行代码 总结 这篇文章主要讲如何根据注释&#xff0c;通过babel插件自动地&#xff0c;给相应函数插入埋点代码&#xff0c;在实现埋点逻辑和业务逻辑分离的基础上&#xff0c;配置更加灵活 这篇文章想要达到的效…

010.cat、find

1、用cat进行拼接 cat命令能够显示或拼接文件内容&#xff0c;不过它的能力远不止如此。比如说&#xff0c;cat能够将标准输入数据与文件数据组合在一起。通常的做法是将stdin重定向到一个文件&#xff0c;然后再合并两个文件。而cat命令一次就能搞定这些操作。 用cat读取文件…

Go fsnotify简介

fsnotify是一个用Go编写的文件系统通知库。它提供了一种观察文件系统变化的机制&#xff0c;例如文件的创建、修改、删除、重命名和权限修改。它使用特定平台的事件通知API&#xff0c;例如Linux上的inotify&#xff0c;macOS上的FSEvents&#xff0c;以及Windows上的ReadDirec…

中小企业如何最大程度地利用CRM系统的潜力?

在当今竞争激烈的商业世界中&#xff0c;客户关系管理&#xff08;CRM&#xff09;数字化转型已经成为大企业成功的重要秘诀。大型跨国公司如亚马逊、苹果和微软等已经在CRM数字化方面走在了前列&#xff0c;实现了高度个性化的客户体验&#xff0c;加强了客户忠诚度。 然而&a…

手把手云开发一个小程序-(二)-uniclould的购买和默认库的使用

一,前言 因为平时喜欢记录一些文案,看小说或者上网冲浪的时候,遇到拍案叫绝的文字,就会截图保存下来,但是时间久了,手机里截图保留了很多,却不会再去看,想删除又舍不得,于是就想着自己开发个文案记录的小程序.自用的同时让有同样需求的人也能用. 目前已经把第一个版本开发完了…

【教3妹学编程-算法题】最长奇偶子数组

3妹&#xff1a;2哥&#xff0c;你有没有看到新闻&#xff0c; 网红快乐小赵去世了。 2哥 :啊&#xff1f; 这么突然 3妹&#xff1a;是啊&#xff0c; 伤心&#xff0c;以前还特别喜欢他的作品&#xff0c;幽默搞笑。 2哥&#xff1a;哎&#xff0c;人有悲欢离合&#xff0c; …

Open3D 进阶(17)间接平差拟合二维直线

目录 一、算法原理二、代码实现三、结果展示本文由CSDN点云侠原创,原文链接。 一、算法原理 见:PCL 间接平差法拟合二维直线。 二、代码实现 import numpy as np import open3d as o3d import matplotlib.pyplot as plt

关于数据mysql ->maxwell->kafka的数据传输

个人名片&#xff1a; &#x1f405;作者简介&#xff1a;一名大三在校生&#xff0c;热爱生活&#xff0c;爱好敲码&#xff01; \ &#x1f485;个人主页 &#x1f947;&#xff1a;holy-wangle ➡系列内容&#xff1a; &#x1f5bc;️ tkinter前端窗口界面创建与优化 &…

鸿蒙原生应用开发-折叠屏、平板设备服务卡片适配

一、多设备卡片适配原则 为不同尺寸的卡片提供不同的功能 在卡片开发过程中请考虑适配不同尺寸的设备&#xff0c;特别是在折叠屏和平板设备上&#xff0c;设备屏幕尺寸的变化直接影响了卡片内容的展示。请发挥想象力设计具有自适应能力的卡片&#xff0c;避免在卡片内容不做…

git clone:SSL: no alternative certificate subject name matches target host name

git clone 时的常见错误&#xff1a; fatal: unable to access ‘https://ip_or_domain/xx/xx.git/’: SSL: no alternative certificate subject name matches target host name ‘ip_or_domain’ 解决办法&#xff1a; disable ssl verify git config --global http.sslVe…

[Jenkins] Docker 安装Jenkins及迁移流程

系统要求 最低推荐配置: 256MB可用内存1GB可用磁盘空间(作为一个Docker容器运行jenkins的话推荐10GB) 为小团队推荐的硬件配置: 1GB可用内存50 GB 可用磁盘空间 软件配置: Java 8—无论是Java运行时环境&#xff08;JRE&#xff09;还是Java开发工具包&#xff08;JDK&#xff…

前端 react 面试题 (一)

文章目录 vue与react的区别。react的生命周期有哪些及它们的作用。setState是同步的还是异步的。如何更新数据后&#xff0c;立刻获取最新的dom或者更新后的数据。使用回调函数&#xff1a;在生命周期方法中处理&#xff1a; 函数式组件和class组件的区别。class组件函数式组件…
最新文章