《程序猿入职必会(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}服务
     */
    @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

  • 25
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 9
    评论
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

战神刘玉栋

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值