当前位置: 首页 > news >正文

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

📢 大家好,我是 【战神刘玉栋】,有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}服务*/@Autowiredprivate ${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

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 【JavaScript】详解数组方法 fill()
  • 【已解决】VSCode连接Linux云服务器,代码写着写着服务器突然挂了是怎么回事?
  • 【爬虫实战】利用代理爬取电商数据
  • 【Python】Django Web 框架
  • STM32Cubemxide使用freertos的消息队列(QUEUE)
  • xss漏洞(五,xss-labs靶场搭建及简单讲解)
  • 03 LVS+Keepalived群集
  • Windows应急响应-排查方式
  • C++ 中基本数据类型所占字节简单说明
  • IsaacLab | Workflow 中 rsl_rl 的 play.py 脚本精读
  • Linux useradd命令
  • pytorch学习笔记6 tensor拼接和拆分
  • ts-node 报错 ERR_UNKNOWN_FILE_EXTENSION
  • XXE-lab-master靶场:PHP_xxe
  • 【生成式人工智能-三-promote 神奇咒语RL增强式学习RAG】
  • -------------------- 第二讲-------- 第一节------在此给出链表的基本操作
  • 《Java8实战》-第四章读书笔记(引入流Stream)
  • CNN 在图像分割中的简史:从 R-CNN 到 Mask R-CNN
  • const let
  • css系列之关于字体的事
  • Mac 鼠须管 Rime 输入法 安装五笔输入法 教程
  • MySQL主从复制读写分离及奇怪的问题
  • Python语法速览与机器学习开发环境搭建
  • 对话 CTO〡听神策数据 CTO 曹犟描绘数据分析行业的无限可能
  • 技术胖1-4季视频复习— (看视频笔记)
  • 码农张的Bug人生 - 初来乍到
  • 每天一个设计模式之命令模式
  • 如何正确配置 Ubuntu 14.04 服务器?
  • 世界上最简单的无等待算法(getAndIncrement)
  • 详解移动APP与web APP的区别
  • 用Python写一份独特的元宵节祝福
  • 智能情侣枕Pillow Talk,倾听彼此的心跳
  • ​Java基础复习笔记 第16章:网络编程
  • ​直流电和交流电有什么区别为什么这个时候又要变成直流电呢?交流转换到直流(整流器)直流变交流(逆变器)​
  • "无招胜有招"nbsp;史上最全的互…
  • (1)虚拟机的安装与使用,linux系统安装
  • (Forward) Music Player: From UI Proposal to Code
  • (PADS学习)第二章:原理图绘制 第一部分
  • (Redis使用系列) Springboot 实现Redis 同数据源动态切换db 八
  • (二)springcloud实战之config配置中心
  • (二)WCF的Binding模型
  • (附源码)ssm学生管理系统 毕业设计 141543
  • (附源码)计算机毕业设计ssm本地美食推荐平台
  • (附源码)计算机毕业设计大学生兼职系统
  • (附源码)小程序儿童艺术培训机构教育管理小程序 毕业设计 201740
  • (三)uboot源码分析
  • (数据结构)顺序表的定义
  • (一)springboot2.7.6集成activit5.23.0之集成引擎
  • (转)为C# Windows服务添加安装程序
  • ***通过什么方式***网吧
  • .libPaths()设置包加载目录
  • .NET Core实战项目之CMS 第一章 入门篇-开篇及总体规划
  • .net core使用EPPlus设置Excel的页眉和页脚
  • .NET Framework、.NET Core 、 .NET 5、.NET 6和.NET 7 和.NET8 简介及区别
  • .NET设计模式(8):适配器模式(Adapter Pattern)