📢 大家好,我是 【战神刘玉栋】,有10多年的研发经验,致力于前后端技术栈的知识沉淀和传播。 💗
🌻 CSDN入驻不久,希望大家多多支持,后续会继续提升文章质量,绝不滥竽充数,欢迎多多交流。👍
文章目录
写在前面的话
本系列博文已连载到第九篇,看过前面几篇系列文章,应该发现了,博主在创建完教师信息表后,若干前后端核心代码基本都使用代码生成器生成,手敲代码却是甚少,本篇文章就介绍一下,如何在日常工作借助代码生成器快速开发。
关联文章:
《程序猿入职必会(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 操作。
- CodeSmith 简介:CodeSmith 是一个强大的代码生成器,支持多种编程语言和框架。这是一个强大的代码生成工具,支持多种编程语言和数据库。它提供了强大的模板功能,用户可以创建复杂的代码模板来生成代码。 特点:
- 提供了丰富的模板库,可以根据需要进行自定义。
- 支持与多种数据库和 ORM 框架集成。
适用场景:适合需要生成大量重复代码的项目。
6. Yeoman
简介:Yeoman 是一个前端工具,能够生成项目的骨架代码。一个基于 Node.js 的生成工具,可以用于生成各种类型的项目,包括前端和后端项目。
特点:
- 提供了丰富的生成器,可以快速生成前端项目结构。
- 支持自定义生成器。
适用场景:适合前端开发,尤其是需要快速搭建项目的场景。
自定义能力说明
大多数代码生成器允许你自定义模板。这通常是必要的,因为每个公司的框架和编码规范都有所不同。自定义模板可以确保生成的代码符合你的特定需求。模板通常使用模板引擎(如Freemarker或Velocity)来编写,它们允许你以编程方式创建代码结构,并根据数据库模型动态填充内容。
实战效果说明
Tips:上面介绍了若干代码生成器,都是优秀的产品,其实也没必要去纠结使用哪个,能解决自己的需要即可。
选择合适的代码生成器主要取决于你的项目需求、技术栈以及团队的开发习惯。无论选择哪个工具,通常都需要根据公司的代码规范和框架进行模板的自定义,以确保生成的代码符合团队的标准。
博主的项目采用 Rapid-Generator ,它是一个不错的选择,尤其是在需要快速生成 CRUD 代码的场景中。
【确定要生成的文件范围】
要生成的文件包含但不限于:controller、service、mapper、xml、entity、api.js、page.vue
【编辑模板思路】
要快速生成上面一系列的代码,核心就是模板制作。
先以控制层代码做一个示例说明,下方是模板示例。
- 先根据自身框架,手写实现一个业务表对应的增删改查逻辑,包括前后端,包装功能可用;
- 将对应代码贴到模板文件中,将动态部分用相关变量替换;
- 创建表后,测试生成效果;
<#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;importcom.lw.sbdemo2.common.web.anno.ResultController;importio.swagger.annotations.Api;importio.swagger.annotations.ApiImplicitParam;importio.swagger.annotations.ApiImplicitParams;importio.swagger.annotations.ApiOperation;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.web.bind.annotation.*;importjava.util.Date;importjava.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}")publicclass ${className}ControllerextendsBaseController{/**
* ${table_chn}服务
*/@Autowiredprivate ${className}Service ${classNameLower}Service;@ApiOperation(value ="获取${table_chn}列表")@GetMapping("")publicList<${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")publicPageInfo<${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(@PathVariableString id){return ${classNameLower}Service.getById(id);}@ApiOperation(value ="创建${table_chn}")@PostMapping("/insert")publicvoidinsert(${className} ${classNameLower}){<#list table.columns as column><#if column.sqlName == 'CREATED_TIME'>
${classNameLower}.setCreatedTime(newDate());</#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")publicvoidupdate(${className} ${classNameLower}){<#list table.columns as column><#if column.sqlName == 'MODIFIED_TIME'>
${classNameLower}.setModifiedTime(newDate());</#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")publicvoid delete${className}(${className} ${classNameLower}){
${classNameLower}Service.delete(${classNameLower});}}
【修改配置文件】
调整 generator.xml 配置文件,配置代码生成器相关属性。
<?xml version="1.0" encoding="GBK"?><!DOCTYPEpropertiesSYSTEM"http://java.sun.com/dtd/properties.dtd"><properties><!-- 包路径前缀com.zoe.optimus.service.模块名 --><entrykey="basepackage">com.lw.sbdemo2</entry><!-- 项目模块名 已basepackage的模块名一致 --><entrykey="m_eng"></entry><!-- 该表所在的包名称 用于文件路径--><entrykey="nextPackageFileUrl"></entry><!-- 该表所在的包名称 用于api路径 --><entrykey="nextPackageApiUrl"></entry><!-- 该表所在的包名称 用于bean别名 --><entrykey="nextPackageBean"></entry><!-- 是否是字典 1;是,0:不是 --><entrykey="is_dict">0</entry><!-- 显示在java文件里的中文名字 --><entrykey="table_chn">床头卡信息表</entry><!-- 显示在java文件里的author --><entrykey="author">ZhanShen</entry><entrykey="namespace">WEB-INF/template</entry><entrykey="outRoot">.\generator-output</entry><!-- 数据库类型映射 --><entrykey="java_typemapping.java.sql.Timestamp">java.util.Date</entry><entrykey="java_typemapping.java.sql.Date">java.util.Date</entry><entrykey="java_typemapping.java.sql.Time">java.util.Date</entry><entrykey="java_typemapping.java.lang.Byte">Integer</entry><entrykey="java_typemapping.java.lang.Short">Integer</entry><entrykey="java_typemapping.java.math.BigDecimal">Long</entry><entrykey="java_typemapping.java.sql.Clob">String</entry><entrykey="java_typemapping.java.sql.Blob">byte[]</entry><!-- Mysql --><entrykey="jdbc_url"></entry><entrykey="jdbc_driver"></entry><entrykey="jdbc_username"></entry><entrykey="jdbc_password"></entry></properties>
【生成演示】
进入主目录,输入cmd,打开命令窗口
输入相关的表,输入:
gen 表名
,即可生成相应代码,拷贝到项目中即可。
理想成果是文件导入后,直接可用,不用调整任何代码。
总结陈词
此篇文章介绍了
代码生成器
的基础运用,仅供学习参考。
选择合适的代码生成器需要据公司框架、业务需求和团队的技术水平进行综合考虑,建议根据实际情况选择合适的代码生成器,并进行必要的自定义和测试。
💗 后续会逐步分享企业实际开发中的实战经验,有需要交流的可以联系博主。
版权归原作者 战神刘玉栋 所有, 如有侵权,请联系我们删除。