《程序猿入职必会(9) · 用代码生成器快速开发》

news2024/11/23 14:59:20

📢 大家好,我是 【战神刘玉栋】,有10多年的研发经验,致力于前后端技术栈的知识沉淀和传播。 💗
🌻 CSDN入驻不久,希望大家多多支持,后续会继续提升文章质量,绝不滥竽充数,欢迎多多交流。👍

文章目录

    • 写在前面的话
    • 代码生成器简介
    • 常见代码生成器
    • 自定义能力说明
    • 实战效果说明
    • 总结陈词

CSDN.gif

写在前面的话

本系列博文已连载到第九篇,看过前面几篇系列文章,应该发现了,博主在创建完教师信息表后,若干前后端核心代码基本都使用代码生成器生成,手敲代码却是甚少,本篇文章就介绍一下,如何在日常工作借助代码生成器快速开发。

关联文章:
《程序猿入职必会(1) · 搭建拥有数据交互的 SpringBoot 》
《程序猿入职必会(2) · 搭建具备前端展示效果的 Vue》
《程序猿入职必会(3) · SpringBoot 各层功能完善 》
《程序猿入职必会(4) · Vue 完成 CURD 案例 》
《程序猿入职必会(5) · CURD 页面细节规范 》
《程序猿入职必会(6) · 返回结果统一封装》
《程序猿入职必会(7) · 前端请求工具封装》
《程序猿入职必会(8) · 整合 Knife4j 接口文档》


代码生成器简介

代码生成器是一种开发工具,可以帮助开发者快速生成重复性高的代码,从而极大地提高开发效率,尤其是在需要重复生成相似代码的场景中。
日常开发过程中,重复性工作最大的,无非是各个业务表对应的各层业务代码,都有各自的基础增删改查业务,这其中涉及的前后端代码,基本代码都相似,也就是程序猿日常的拧螺丝工作。
通常在软件公司中,针对前后端开发,都有封装相关核心框架,相应的,各层业务代码也都有相应规约,比如后端 Spring 开发常见的 Controller、Service、Mapper、Entity、SqlXml,前端 Vue 开发常见的 Page.vue、Api.js。因此,一款优秀的代码生成器应该具备与框架结合的能力,即模板自定义功能。


常见代码生成器

先列举一些常见的代码生成器产品。

**1. MyBatis Generator **
简介:MyBatis Generator 是一个用于生成 MyBatis 和 MyBatis 相关代码的工具,这是 MyBatis 官方提供的代码生成器,主要用于生成 MyBatis 的 Mapper 接口和 XML 文件。它支持自定义模板,可以很好地与 Spring Boot 集成。
特点:

  • 支持 XML 和注解配置。
  • 可以生成实体类、Mapper 接口、XML 映射文件等。
  • 可以通过自定义模板来适应公司的代码风格。

适用场景:适合使用 MyBatis 的项目,尤其是需要快速生成数据库操作代码的场景。

2. JHipster
简介:JHipster 是一个开发平台,用于生成、开发和部署 Spring Boot + Angular/React/Vue 的 Web 应用程序,一个全栈式代码生成器,可以生成完整的 Web 应用程序,包括前后端代码。
特点:

  • 提供了丰富的生成选项,可以生成完整的应用程序架构。
  • 支持自定义生成模板。
  • 集成了多种前端框架和后端技术。

适用场景:适合需要快速搭建全栈应用的项目。

3. Spring Roo
简介:Spring Roo 是一个快速开发框架,能够通过命令行生成 Spring 应用程序的代码。提供了一个命令行界面,可以快速生成CRUD操作、数据库访问层等。
特点:

  • 支持快速生成 Spring MVC、Spring Data JPA 等代码。
  • 可以通过自定义模板来适应特定需求。

适用场景:适合使用 Spring 技术栈的项目。

4. Rapid-Generator(√)
简介:Rapid-Generator 是一个轻量级的代码生成器,支持多种模板引擎(如 FreeMarker、Velocity)。这是一个非常强大的代码生成器工具,可以根据数据库表结构自动生成 CRUD 代码、DTO、Mapper 等,它支持自定义模板,可以很好地与 Spring Boot、MyBatis 等框架集成,使用起来非常方便,是很多公司的首选。
特点:

  • 提供了简单易用的命令行界面。
  • 支持自定义模板,可以根据公司需求进行调整。
  • 适合快速生成 CRUD 代码。

适用场景:适合需要快速生成代码的项目,尤其是 CRUD 操作。

  1. CodeSmith
    简介:CodeSmith 是一个强大的代码生成器,支持多种编程语言和框架。这是一个强大的代码生成工具,支持多种编程语言和数据库。它提供了强大的模板功能,用户可以创建复杂的代码模板来生成代码。
    特点:
  • 提供了丰富的模板库,可以根据需要进行自定义。
  • 支持与多种数据库和 ORM 框架集成。

适用场景:适合需要生成大量重复代码的项目。

6. Yeoman
简介:Yeoman 是一个前端工具,能够生成项目的骨架代码。一个基于 Node.js 的生成工具,可以用于生成各种类型的项目,包括前端和后端项目。
特点:

  • 提供了丰富的生成器,可以快速生成前端项目结构。
  • 支持自定义生成器。

适用场景:适合前端开发,尤其是需要快速搭建项目的场景。


自定义能力说明

大多数代码生成器允许你自定义模板。这通常是必要的,因为每个公司的框架和编码规范都有所不同。自定义模板可以确保生成的代码符合你的特定需求。模板通常使用模板引擎(如Freemarker或Velocity)来编写,它们允许你以编程方式创建代码结构,并根据数据库模型动态填充内容。


实战效果说明

Tips:上面介绍了若干代码生成器,都是优秀的产品,其实也没必要去纠结使用哪个,能解决自己的需要即可。

选择合适的代码生成器主要取决于你的项目需求、技术栈以及团队的开发习惯。无论选择哪个工具,通常都需要根据公司的代码规范和框架进行模板的自定义,以确保生成的代码符合团队的标准。
博主的项目采用 Rapid-Generator ,它是一个不错的选择,尤其是在需要快速生成 CRUD 代码的场景中。

【确定要生成的文件范围】
要生成的文件包含但不限于:controller、service、mapper、xml、entity、api.js、page.vue

【编辑模板思路】
要快速生成上面一系列的代码,核心就是模板制作。
先以控制层代码做一个示例说明,下方是模板示例。

  1. 先根据自身框架,手写实现一个业务表对应的增删改查逻辑,包括前后端,包装功能可用;
  2. 将对应代码贴到模板文件中,将动态部分用相关变量替换;
  3. 创建表后,测试生成效果;
<#assign className = table.className>   
<#assign classNameLower = className?uncap_first> 
<#assign table_chn = table.remarks>
<#assign pkColumn = table.pkColumn>
<#assign pkColumnName = table.pkColumn.columnName>
<#assign pkColumnNameLower = table.pkColumn.columnNameLower>
package ${basepackage}.web<#if nextPackageFileUrl != "">.${nextPackageFileUrl}</#if>;

import ${basepackage}.common.utils.IdUtils;
import ${basepackage}.common.web.anno.Required;
import ${basepackage}.common.base.BaseController;
import ${basepackage}.common.vo.PageInfo;
import ${basepackage}.entity<#if nextPackageFileUrl != "">.${nextPackageFileUrl}</#if>.${className};
import ${basepackage}.service<#if nextPackageFileUrl != "">.${nextPackageFileUrl}</#if>.${className}Service;
import com.lw.sbdemo2.common.web.anno.ResultController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

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

/**
 * <p>标题: ${table_chn}服务 - 请求控制层</p>
 * <p>描述: </p>
 * <p>版权: Copyright (c) ${now?string('yyyy')}</p>
 * <p>公司: 山人行工作室</p>
 *
 * @version: 1.0
 * @author: ${author}
 * @date ${now?date}
 */
@ResultController
@Api(value = "${className}Controller", tags = {"${table_chn}服务"})
@RequestMapping(value = "/<#if nextPackageApiUrl != "">${nextPackageApiUrl}/</#if>${classNameLower}")
public class ${className}Controller extends BaseController {

    /**
     * ${table_chn}服务
     */
    @Autowired
    private ${className}Service ${classNameLower}Service;
	
	@ApiOperation(value = "获取${table_chn}列表")
    @GetMapping("")
    public List<${className}> findList(${className} ${classNameLower}) {
        return ${classNameLower}Service.findList(${classNameLower});
    }

    @ApiOperation(value = "获取${table_chn}列表(分页)", response = PageInfo.class)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "query", value = "关键词", dataType = "string"),
            @ApiImplicitParam(name = "pageNum", value = "当前页码", required = true, dataType = "int"),
    })
    @GetMapping(value = "/page")
    public PageInfo<${className}> page(String query, @Required("pageNum") PageInfo pageInfo, ${className} ${classNameLower}) {
        return ${classNameLower}Service.findListPage(query, pageInfo, ${classNameLower});
    }

    @ApiOperation(value = "获取${table_chn}详细信息", notes = "根据url的id来获取${table_chn}详细信息")
    @ApiImplicitParam(name = "id", value = "${table_chn}ID", required = true, dataType = "String")
    @GetMapping("/{id}")
    public ${className} get(@PathVariable String id) {
        return ${classNameLower}Service.getById(id);
    }

    @ApiOperation(value = "创建${table_chn}")
    @PostMapping("/insert")
    public void insert(${className} ${classNameLower}) {
		<#list table.columns as column>
			<#if column.sqlName == 'CREATED_TIME'>
		${classNameLower}.setCreatedTime(new Date());
			</#if>
		</#list>
        ${classNameLower}.set${pkColumnName}(IdUtils.uuid());
        ${classNameLower}Service.insert(${classNameLower});
    }

    @ApiOperation(value = "更新${table_chn}详细信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "${table_chn}ID", required = true, paramType = "query", dataType = "String")
    })
    @PostMapping("/update")
    public void update(${className} ${classNameLower}) {
		<#list table.columns as column>
			<#if column.sqlName == 'MODIFIED_TIME'>
		${classNameLower}.setModifiedTime(new Date());
			</#if>
		</#list>
        ${classNameLower}Service.update(${classNameLower});
    }

    @ApiOperation(value = "删除${table_chn}", notes = "删除${table_chn}")
    @ApiImplicitParam(name = "id", value = "${table_chn}ID", required = true, paramType = "query", dataType = "String")
    @PostMapping("/delete")
    public void delete${className}(${className} ${classNameLower}) {
        ${classNameLower}Service.delete(${classNameLower});
    }
    
}

【修改配置文件】
调整 generator.xml 配置文件,配置代码生成器相关属性。

<?xml version="1.0" encoding="GBK"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
	<!-- 包路径前缀com.zoe.optimus.service.模块名 -->
	<entry key="basepackage">com.lw.sbdemo2</entry>

	<!-- 项目模块名 已basepackage的模块名一致  -->
	<entry key="m_eng"></entry>
	
	<!-- 该表所在的包名称 用于文件路径-->
	<entry key="nextPackageFileUrl"></entry>
	
	<!-- 该表所在的包名称 用于api路径 -->
	<entry key="nextPackageApiUrl"></entry>
	
	<!-- 该表所在的包名称 用于bean别名 -->
	<entry key="nextPackageBean"></entry>
	
	<!-- 是否是字典 1;是,0:不是  -->
	<entry key="is_dict">0</entry>
	
	<!-- 显示在java文件里的中文名字 -->
	<entry key="table_chn">床头卡信息表</entry>
	
	<!-- 显示在java文件里的author  -->
	<entry key="author">ZhanShen</entry>
	
	<entry key="namespace">WEB-INF/template</entry>
	
	<entry key="outRoot">.\generator-output</entry>		
	
	<!-- 数据库类型映射  -->
	<entry key="java_typemapping.java.sql.Timestamp">java.util.Date</entry>
	<entry key="java_typemapping.java.sql.Date">java.util.Date</entry>
	<entry key="java_typemapping.java.sql.Time">java.util.Date</entry>	
	<entry key="java_typemapping.java.lang.Byte">Integer</entry>
	<entry key="java_typemapping.java.lang.Short">Integer</entry>
	<entry key="java_typemapping.java.math.BigDecimal">Long</entry>
	<entry key="java_typemapping.java.sql.Clob">String</entry>
	<entry key="java_typemapping.java.sql.Blob">byte[]</entry>
	
	<!-- Mysql  -->
	<entry key="jdbc_url"></entry>
	<entry key="jdbc_driver"></entry>
	<entry key="jdbc_username"></entry>
	<entry key="jdbc_password"></entry>


</properties>

【生成演示】
进入主目录,输入cmd,打开命令窗口
输入相关的表,输入:gen 表名,即可生成相应代码,拷贝到项目中即可。
理想成果是文件导入后,直接可用,不用调整任何代码。
image.png


总结陈词

此篇文章介绍了代码生成器 的基础运用,仅供学习参考。
选择合适的代码生成器需要据公司框架、业务需求和团队的技术水平进行综合考虑,建议根据实际情况选择合适的代码生成器,并进行必要的自定义和测试。
💗 后续会逐步分享企业实际开发中的实战经验,有需要交流的可以联系博主。

CSDN_END.gif

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

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

相关文章

从文字到视频的魔法:CogVideoX让你的创意瞬间成真

CogVideoX 发布 如果有一个工具能够让你轻松跨越这些障碍&#xff0c;瞬间成为短视频高手&#xff0c;你会心动吗&#xff1f;今天&#xff0c;这个梦想终于成为现实。智谱AI最新推出的CogVideoX&#xff0c;正是为你量身打造的AI视频创作神器&#xff01; CogVideoX CogVideoX…

论文辅导 | 基于时空Transformer 网络的隧道交通运行风险 动态辨识方法

辅导文章 模型描述 为了及时发现、评估与应对高速公路隧道交通风险隐患&#xff0c;确保隧道运行安全通畅&#xff0c;构建了基于时空Transformer网络的隧道运行风险状态动态辨识方法。以隧道交通流全域检测数据与关键断面集计数据为输入&#xff0c;通过空间CNN卷积与时序LST…

蜂窝物联智慧农业新篇章:揭秘智慧大棚的科技魅力!

在这个科技日新月异的时代&#xff0c;农业这一古老而重要的行业正经历着前所未有的变革。智慧农业的兴起&#xff0c;尤其是智慧大棚的应用&#xff0c;正悄然改变着我们对传统农业的认知&#xff0c;引领着农业生产进入了一个高效、精准、可持续发展的新时代。今天&#xff0…

怎么查询大数据信用评分?

相信在了解大数据信用评分的时候&#xff0c;不少人都因为大数据信用评分在申贷的时候遭受到过挫折&#xff0c;因为大数据信用已经被很多银行和金融机构作为风险控制的重要依据使用&#xff0c;其中的大数据信用评分&#xff0c;能直观的感知到用户的信用情况。那如何查询大数…

【ESP-IDF】ESP32获取真随机数

ESP32内置一个真随机数发生器。我翻了好几个型号的ESP32的编程指南&#xff0c;都有相关的函数&#xff0c;应该是大部分型号都有&#xff0c;具体有没有还需要对照一下自己手上的ESP32型号。 我们可以从从随机数发生器的寄存器 RNG_DATA_REG 中读取随机数&#xff0c;每个读到…

到底哪款蓝牙耳机才是性价比之王?精选四款平价高品质耳机品牌!

在当前的音频设备市场中&#xff0c;蓝牙耳机已成为众多现代人挑选的热门配件。选蓝牙耳机不同人看重的点不一样&#xff0c;但倘若像我这样喜欢用来听音乐的&#xff0c;就千万别忽视耳机的音质。现在的产品越来越多&#xff0c;到底哪款蓝牙耳机才是性价比之王&#xff1f;一…

html+css 实现hover背景彩色按钮

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享htmlcss 绚丽效果&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495; 文…

数据治理数据管理体系:数据标准、数据中台、数据安全、大数据平台与架构

数据驱动&#xff0c;资产为王&#xff0c;企业竞争的核心逐渐从传统的资源争夺转向了数据价值的挖掘与利用。数据&#xff0c;作为企业的新石油&#xff0c;正以前所未有的速度重塑着商业格局。为了在这场数据革命中占据先机&#xff0c;构建一套完善的数据治理体系显得尤为重…

用户上下文打通+本地缓存Guava

文章目录 &#x1f31e; Sun Frame&#xff1a;SpringBoot 的轻量级开发框架&#xff08;个人开源项目推荐&#xff09;&#x1f31f; 亮点功能&#x1f4e6; spring cloud模块概览常用工具 &#x1f517; 更多信息1.设计1.链路流程2.详细设计 2.网关过滤器获取唯一标识放到Hea…

LSTM长短时记忆网络【数学+图解】

文章目录 1、简介2、门控机制3、LSTM3.1、概念3.2、公式⭐3.3、特点 4、图解LSTM⭐4.1、RNN4.2、时间链条4.3、**记忆单元**&#x1f53a;4.4、LSTM 5、LSTM与GRU的对比6、应用7、训练技巧 &#x1f343;作者介绍&#xff1a;双非本科大三网络工程专业在读&#xff0c;阿里云专…

欧拉系统网络配置

从母盘克隆出一个虚拟机openEuler-node2 如何设定网卡的名称为ehtx x为数字 在内核中禁止使用net.ifnames模块&#xff0c;这样可以让网卡显示为ethx [rootlocalhost ~]# gruuby --update-kernel ALL --args net.ifnames0修改完这个参数过后需要重启系统reboot&#xff0c;让…

4658. 质因数个数、197. 阶乘分解、模板题【线性筛求积性函数】(数论练习题)

目录 4658. 质因数个数 题目描述 运行代码 代码思路 197. 阶乘分解 题目描述 运行代码 代码思路 其他代码 代码思路 模板题【线性筛求积性函数】 题目描述 ​编辑 运行代码 代码思路 4658. 质因数个数 题目描述 4658. 质因数个数 - AcWing题库 运行代码 #in…

银河麒麟V10 审计工具 auditd 内存泄漏问题

问题描述 银河麒麟V10 SP1 审计工具 auditd 引发的内存占用过高&#xff0c; 内存占用171G&#xff0c; 内存一直不释放 解决方案 重启进程 auditd 是银河麒麟的审计工具&#xff0c; 分析是由于 yum 源的特性&#xff0c; 造成审计工具占用内存不释放&#xff0c; 重启 a…

dsc集群添加磁盘空间

在达梦数据库dsc集群保姆级部署文档_达梦数据库文档-CSDN博客这篇文档的基础上操作添加磁盘&#xff0c;进行一个扩容操作。 在生产环境中&#xff0c;数据存储集群&#xff08;DSC&#xff09;的磁盘空间不足是一个常见问题&#xff0c;这可能会导致服务中断或性能下降。为了…

代码随想录算法训练营day35 | 0-1背包理论基础、416. 分割等和子集

碎碎念&#xff1a;加油&#xff01;&#xff01; 参考&#xff1a;代码随想录 0-1背包理论基础 几类背包的区别&#xff1a; 0-1背包的每种物品只有一个 完全背包的每种物品有无限个 多重背包的每种物品的个数各不相同 01背包&#xff1a; 有n件物品和一个最多能背重量为w …

如何开发属于你的智能人才招聘系统:源码解析

今天&#xff0c;小编将从源码解析的角度&#xff0c;带你深入了解如何开发属于你的智能人才招聘系统。 一、为什么选择开发自己的智能招聘系统&#xff1f; 市面上已有许多现成的招聘系统&#xff0c;但这些系统往往无法完全满足企业个性化的需求。通过开发自有系统&#xf…

中小型水库雨水情及大坝安全监测系统完整方案

一、背景 随着气候变化和极端天气事件的频发&#xff0c;中小型水库的安全运行显得愈发重要。为确保水库大坝的稳定性和防洪功能的发挥&#xff0c;建设一套完善的雨水情及大坝安全监测系统显得尤为重要。本文将从系统背景、系统介绍、应用实例和未来展望等方面&#xff0c;对…

【HTML入门】第二十三课 - 【实战】做一个简单的图书详情页

这一节&#xff0c;我们继续用纯HTML来做一个实战小案例。 我找了一个图书详情的页面&#xff0c;就像这样&#xff1a; 这一小节&#xff0c;我们用纯HTML标签&#xff0c;来实现一下这个图书详情的内容。 目录 1 布局分析 2 用到的标签 3 实战代码 1 布局分析 我们看这张…

SQL各种注入详解加案例--持续更新

sql注入 联合查询注入案例手工注入判断是否有SQL注入漏洞 sqlmap工具注入 报错注入常用的函数updatexml()函数案例 floor()涉及的函数实现手工注入sqlmap工具注入 盲注布尔盲注案例手工注入脚本sqlmap自动化工具 时间盲注 post注入GET传参和POST传参案例手工注入sqlmap工具 二次…

Venv复制可以减少Pip install

接前面的一篇博客《PyCharm找不到Python咋办》中遇到的步骤&#xff1a; 有上图的提示&#xff0c;说明需要将原来的venv进行清空。&#xff08;还可以用重命名的方式&#xff0c;这样venv当中的库可以保留&#xff0c;如果Python的版本和原来一样的话&#xff0c;直接覆盖回来…