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

代码生成器使用原理以及使用方法

代码生成器使用原理以及使用方法

版本号:1.0

二Ο二五年二月

目录

文档介绍

1.1编写目的

1.2文档范围

1.3读者对象

系统设计

2.1设计目标

2.2设计思路

2.3代码实现原理

使用方法

3.1如何使用

3.2如何修改?

对原程序的bug修改及简化

4.1 一个bug

4.2 Controler层三个if改成接口形式1->3

4.3引擎中几次替换修改为小的方法调用

4.4改进建议

文档介绍

1.1编写目的

1.让修改者了解代码执行过程,为未来可能的修改做准备。

2.让使用者了解怎么使用,需要输入哪些参数才能执行

1.2文档范围

代码模块组成,代码执行过程解析,先前代码的错误原因分析以及修改方法。

1.3读者对象

有一定java基础 知晓”类” ”注解”这些java内容以及使用方式。

系统设计

2.1设计目标

通用的代码生成器。有几个部分:

第一个部分:代码模板的生成。

第二个部分:webmodelvo参数构建。

第三部分:webmodelvo转为map。

第四部分:构建模板位置及目标位置。

第五部分:引擎实现。

2.2设计思路

代码生成器几乎代码都是是通过 `OnlineGeneratorController` 类开始执行的。正常使用时应当从浏览器端输入,下面介绍的是用main制作的样例输入。

1. 初始化 `onewebModelVo` 对象

WebModelVo onewebModelVo = OneMockWebModelVo.initWo();

作用

  调用 `OneMockWebModelVo.initWo()` 方法,初始化一个 `WebModelVo` 对象 `onewebModelVo`。  

  这个对象通常是一个数据模型(DTO 或 VO),用于描述单表模型的结构。  

  `onewebModelVo` 包含 14 个字段,其中 11 个是 `String` 类型。

思路  

  通过模拟数据(Mock Data)生成一个单表模型的数据对象,为后续的代码生成提供输入。

---

2.初始化 `OnlineGeneratorController` 并设置模板引擎

OnlineGeneratorController onlineGeneratorController = new OnlineGeneratorController();

onlineGeneratorController.setFreemakerEngine(new FreemakerEngineImpl());

作用

  创建 `OnlineGeneratorController` 的实例,用于控制代码生成的过程。  

  设置 `FreemakerEngineImpl` 作为模板引擎,用于解析和生成代码模板。

思路  

  `Freemaker` 是一个模板引擎,可以根据模板文件和数据模型生成代码。  

  这里通过 `setFreemakerEngine` 方法将 `FreemakerEngineImpl` 注入到 `OnlineGeneratorController` 中,以便后续使用。

---

3.生成单表模型的代码

onlineGeneratorController.codeGeneratesingletablewithouttree(onewebModelVo);

作用  

  调用 `codeGeneratesingletablewithouttree` 方法,传入 `onewebModelVo` 作为参数,生成单表模型的代码。

思路  

  `onewebModelVo` 描述了单表模型的结构,`codeGeneratesingletablewithouttree` 方法会根据这个结构生成对应的代码文件(如实体类、DAO、Service 等)。

4.初始化 `treewebModelVo` 对象

WebModelVo treewebModelVo = TreeMockWebModelVo.initWo();

作用  

  调用 `TreeMockWebModelVo.initWo()` 方法,初始化一个 `WebModelVo` 对象 `treewebModelVo`。  

  这个对象通常用于描述树形结构模型(如菜单、分类等)。

思路  

  通过模拟数据生成一个树形结构模型的数据对象,为后续的代码生成提供输入。

5.生成树形结构模型的代码

onlineGeneratorController.codeGeneratesingletablewithouttree(treewebModelVo);

作用

  调用 `codeGeneratesingletablewithouttree` 方法,传入 `treewebModelVo` 作为参数,生成树形结构模型的代码。

思路  

  `treewebModelVo` 描述了树形结构模型的结构,`codeGeneratesingletablewithouttree` 方法会根据这个结构生成对应的代码文件。

6.初始化 `onetomanywebModelVo` 对象

WebModelVo onetomanywebModelVo = OneToManyMockWebModelVo.initWo();

作用  

  调用 `OneToManyMockWebModelVo.initWo()` 方法,初始化一个 `WebModelVo` 对象 `onetomanywebModelVo`。  

  这个对象通常用于描述一对多关系模型(如订单和订单项)。

思路

  通过模拟数据生成一个一对多关系模型的数据对象,为后续的代码生成提供输入。

7.生成一对多关系模型的代码

onlineGeneratorController.codeGeneratesingletablewithouttree(onetomanywebModelVo);

作用  

  调用 `codeGeneratesingletablewithouttree` 方法,传入 `onetomanywebModelVo` 作为参数,生成一对多关系模型的代码。

思路  

  `onetomanywebModelVo` 描述了一对多关系模型的结构,`codeGeneratesingletablewithouttree` 方法会根据这个结构生成对应的代码文件。

---

总结

这段代码的核心思路是通过模拟数据生成不同类型的模型(单表模型、树形结构模型、一对多关系模型),然后调用 `OnlineGeneratorController` 的 `codeGeneratesingletablewithouttree` 方法生成对应的代码。  

每个步骤的作用如下:

1. 初始化数据模型对象(`onewebModelVo`、`treewebModelVo`、`onetomanywebModelVo`)。

2. 设置模板引擎(`FreemakerEngineImpl`)。

3. 调用代码生成方法,根据不同的模型生成代码。

这种设计模式非常适合需要快速生成代码的场景,例如代码生成器、低代码平台等。

2.3代码实现原理

2.2中提到了设计思路以及在什么时候调用什么类什么方法,这些都是在main函数里能看到的 2.3将进入这些类和方法作进一步研究。

先顺着main往下看,WebModelVO是遇到的第一个类,里面的代码定义了一个名为 `WebModelVo` 的 Java 类,它是一个数据模型类(Value Object,VO),用于封装代码生成器所需的相关配置和数据。以下是对代码的详细解释:

1.类定义与注解

```java

@Slf4j

@Data

@SuperBuilder

@AllArgsConstructor

@NoArgsConstructor

@Component

public class WebModelVo implements Serializable {

@Slf4j  

  这是 Lombok 提供的注解,用于自动生成日志对象 `log`,方便在类中直接使用日志功能。

@Data  

  Lombok 注解,自动生成 `getter`、`setter`、`toString`、`equals` 和 `hashCode` 方法。

@SuperBuilder  

  Lombok 注解,支持继承的 Builder 模式,允许通过链式调用的方式创建对象。

@AllArgsConstructor 和 @NoArgsConstructor  

  分别生成全参构造函数和无参构造函数。

@Component

  将该类标记为 Spring 的组件,使其可以被 Spring 容器管理。

implements Serializable

  实现 `Serializable` 接口,表示该类的对象可以被序列化(例如存储到文件或通过网络传输)。

2.字段定义

2.1 基本字段

private String author = "demo"; // 作者名称,默认值为 "demo"

private String testmodulename = ""; // 测试模块名称

private String deploymodulename = ""; // 部署模块名称

private String testuserDefinePackage = ""; // 测试用户自定义包名

private String deployuserDefinePackage = ""; // 部署用户自定义包名

private EnumDeployWay enumDeployWay; // 部署方式枚举

 这些字段用于存储代码生成器的配置信息,例如作者名称、模块名称、包名等。

 部分字段有默认值(如 `author`),其他字段需要外部赋值。

2.2 客户端相关字段

@NotEmpty

@Length(min = 10, max = 50)

private String codefromClientGUID = UUID.randomUUID().toString(); // 客户端生成的唯一标识

```

-@NotEmpty

  表示该字段不能为空。

@Length(min = 10, max = 50)

  表示该字段的长度必须在 10 到 50 之间。

UUID.randomUUID().toString()

  生成一个唯一的标识符,用于标识客户端请求。

2.3 输出目录字段

@NotNull

private String destinationOutPutDir; // 代码生成目录

@Length(min = 0, max = 100)

private String frontDestionOutPutDir; // 前端代码生成目录

@NotNull  

  表示该字段不能为 `null`。

@Length(min = 0, max = 100)  

  表示该字段的长度不能超过 100。

2.4 服务名称与包名

private String servicename = "service"; // 服务名称,默认值为 "service"

@Length(min = 5, max = 50)

private String packageName; // 包名,长度在 5 到 50 之间

servicename

  表示服务名称,默认值为 `"service"`。

packageName

  表示代码生成的包名,长度限制在 5 到 50 之间。

2.5 模型类型与表信息

private String jformType = "1"; // 表单类型,默认值为 "1"

@NotNull

private EnumModelType modeltype; // 模型类型枚举

@NotNull

@Valid

private TableVoDomain tableVoDomain; // 表信息对象

jformType  

  表示表单类型,默认值为 `"1"`。

EnumModelType  

  枚举类型,表示模型的类型(如单表模型、树形模型等)。

TableVoDomain  

  表示表信息的对象,使用 `@Valid` 注解表示需要对该对象进行嵌套验证。

3.设计思路

数据封装  

  `WebModelVo` 类封装了代码生成器所需的所有配置信息,包括作者、模块名称、包名、输出目录、模型类型等。

数据验证:  

  使用 Hibernate Validator 注解(如 `@NotEmpty`、`@NotNull`、`@Length`)对字段进行校验,确保数据的合法性。

默认值  

  部分字段(如 `author`、`servicename`、`jformType`)设置了默认值,简化了对象创建过程。

嵌套对象  

  通过 `TableVoDomain` 对象封装表信息,支持复杂数据结构的嵌套验证。

4.使用场景

代码生成器  

  该类用于代码生成器的配置管理,通过传入不同的 `WebModelVo` 对象,生成不同类型的代码(如单表模型、树形模型等)。

数据校验

  通过 Hibernate Validator 注解,确保传入的数据合法,避免生成错误的代码。

Spring 集成  

  通过 `@Component` 注解,该类可以被 Spring 容器管理,方便在其他组件中注入和使用。

总结

`WebModelVo` 是一个用于代码生成器的数据模型类,封装了代码生成所需的配置信息,并通过注解实现了数据校验和默认值设置。它的设计简洁且易于扩展,适合用于代码生成器、低代码平台等场景。

OneMockWebMode.intWo()的使用

public static WebModelVo initWo() throws Exception{
    WebModelVo wm = initWebModel();
    setWebModelWithoutTree(wm);
    return wm;
}//此方法在main第一个地方用到过 用于给别的变量赋值
//initWo 是一个静态方法,用于初始化并返回一个 WebModelVo 对象。
//该方法调用了两个辅助方法:initWebModel() 和 setWebModelWithoutTree(WebModelVo wm)。

这里的两个辅助方法不再作详细介绍 有兴趣可以观看 他们在同一个目录底下。

OnlineGeneratorController onlineGeneratorController=new OnlineGeneratorController();
onlineGeneratorController.setFreemakerEngine(new FreemakerEngineImpl());

这里创建了onlineGeneratorController这个变量并实例化 下文简称小o

第二行,帮助小o选择了FreemakerEngine接口底下的FreemakerEngineImpl这个类,小o里面的freemakerEngine变量接的就是FreemakerEngineImpl类了

注意!!!这个 FreemakerEngineImpl 类是一个基于 FreeMarker 模板引擎的代码生成器实现类。它的主要功能是根据模板文件和输入的数据模型(Map<String, Object>),生成目标代码文件,在模板路径和目标路径的地方用到了硬编码,直接移植有可能出错。

onlineGeneratorController.codeGeneratesingletablewithouttree(onewebModelVo)

从这一步,正式开始执行引擎作用

这段代码是一个 Spring Boot 控制器中的方法,用于根据传入的 `WebModelVo` 对象生成代码文件。它通过调用 `FreemakerEngine` 实现类(如 `FreemakerEngineImpl`)来处理 FreeMarker 模板,生成目标代码文件。以下是代码的详细解释:

1.方法签名

public Result<?> codeGeneratesingletablewithouttree(@RequestBody @Validated WebModelVo webModelVo) throws Exception

作用

   这是一个 RESTful API 方法,用于处理 POST 请求。

   接收一个 JSON 格式的请求体,并将其转换为 `WebModelVo` 对象。

   使用 `@Validated` 注解对 `WebModelVo` 对象进行校验。

返回值

   返回 `Result<?>` 对象,表示操作结果(成功或失败)。

2.方法逻辑

2.1 初始化模板路径

 定义一个空字符串 `templatepath`,用于存储模板路径。

 创建一个 `ExtTemplateLocaltion` 对象,用于管理模板路径。

2.2 初始化数据模型

 创建一个 `Map<String, Object>` 对象 `map`,用于存储模板中需要替换的变量。

 从 `webModelVo` 中获取模型类型(`enumModelType`),并根据模型类型设置不同的模板路径和数据模型。

2.3 根据模型类型处理不同场景

`default.one`(单表模型)

   设置模板路径为单表模型的路径。

   使用 `OneMapSet` 类生成数据模型(`map`)。

  templatepath = "C:\\Users\\413448405\\Desktop\\codetemplateservice-master\\jeecg-boot\\jeecg-module-system\\jeecg-system-biz\\src\\main\\resources\\jeecg\\code-template-online\\default\\one\\java";

  ParentMapSetFromWebModelVo oneMapSet = new OneMapSet();

  oneMapSet.buildMap(map, webModelVo);

`default.tree`(树形结构模型)

   设置模板路径为树形结构模型的路径。

   使用 `TreeMapSet` 类生成数据模型(`map`)。

  templatepath = "C:\\Users\\413448405\\Desktop\\codetemplateservice-master\\jeecg-boot\\jeecg-module-system\\jeecg-system-biz\\src\\main\\resources\\jeecg\\code-template-online\\default\\tree\\java";

  new TreeMapSet().buildMap(map, webModelVo);

`default.onetomany`(一对多关系模型):

设置模板路径为一对多关系模型的路径。

  使用 `OneToManyMapSet` 类生成数据模型(`map`),包括主表和子表的信息。

  templatepath = "C:\\Users\\413448405\\Desktop\\codetemplateservice-master\\jeecg-boot\\jeecg-module-system\\jeecg-system-biz\\src\\main\\resources\\jeecg\\code-template-online\\erp\\onetomany\\java";

  OneToManyMapSet om = new OneToManyMapSet();

  om.buildMap(map, webModelVo);

  om.buildSonTableMap(map, webModelVo);

  om.buildSonTableColumnMap(map, webModelVo);

  map.put("ftl_description", webModelVo.getTableVoDomain().getTableTxt());

2.4补充数据模型

 向 `map` 中添加当前日期和格式化工具类:

  map.put("currentDate", NonceUtils.nowformat());

  map.put("Format", new SimpleFormat());

 2.5设置生成文件的路径

创建一个 `ExtDestinationLocation` 对象,用于管理生成文件的目标路径。

设置实体名称和包名:

  destinationLocation.setEntityname(webModelVo.getTableVoDomain().getEntityName());

  destinationLocation.setEntitypackage(webModelVo.getPackageName());

 如果 `webModelVo` 中包含测试模块名称,则使用测试模块名称作为包名:

  if (webModelVo.getTestmodulename() != null) {

      destinationLocation.setEntitypackage(webModelVo.getTestmodulename());

  }

2.6 生成文件

 调用 `freemakerEngine.processextenh` 方法,生成目标代码文件:

  freemakerEngine.processextenh(map, templateLocaltion, destinationLocation);

2.7 返回结果

 返回操作成功的消息:

  return Result.ok("转换成功");

3. 代码中的关键点

模板路径

   模板路径是硬编码的,建议将路径配置在配置文件中,便于维护和移植。

数据模型生成

   根据不同的模型类型(单表、树形结构、一对多关系),调用不同的类(如 `OneMapSet`、`TreeMapSet`、`OneToManyMapSet`)生成数据模型。

文件生成

使用 `FreemakerEngine` 实现类(如 `FreemakerEngineImpl`)处理 FreeMarker 模板,生成目标代码文件。

使用方法

3.1如何使用

本程序的要点就在于FreemakerEngine这一部分,引擎有三个输入 分别是map,模板路径,目标路径,简单原理则为将map内容贴到模板上生成到目标路径上。调用OnlineGeneratorController 里的内容可以修改输入的map,更改templatepath可以变更模板位置,更改destinationLocation可以更新目标路径

3.2如何修改?

如果想增加模版类型,就新增一个类挂在Select接口下面,如图

如果想修改生成位置 在下图所示部分修改

destinationLocation类如图部分 修改路径(生成位置)

对原程序的bug修改及简化

4.1 一个bug

Bug位于FreemakerEngineImpl类中,原先代码实现生成结束后,tablename这一位置永远是null,经过debug发现在引擎部分tablenanme根本没有被添加到路径上,经过更改后tablename已经被添加,在图中if和else中用了两种方式,if中使用destinationLocation.getEntitypackage()方法从传入的参数找路径,else则是用String entitypackage = (String) map.get("tableName");直接去上一场map对象里去挖路径。

4.2 Controler层三个if改成接口形式1->3

把它改成接口类型 这样后续改进时候只需要新增类 而不需要在controller里面修改

以前输入方式是直接更改代码,更改为从浏览器输入更为合适。

图中红框为代替controller里if的部分

4.3引擎中几次替换修改为小的方法调用

4.4改进建议

用绝对路径非常不友好,不方便移植。

相关文章:

  • 缓存系统-基本概述
  • 在Docker上安装Mongo及Redis-NOSQL数据库
  • 从 Acrobat 到 LiveCycle 的英语词源
  • 如何使用postman
  • FPGA 44 ,SDC 时序约束标准( 深度解析 SDC 标准 )
  • FPGA 43 ,UDP 协议详细解析( FPGA 中的 UDP 协议 )
  • 数据结构排序算法合集
  • Docker 快速搭建一个基于 GPT-Vis 组件的统计图表生成服务
  • Python 目录操作详解
  • 【学习笔记】nlohmannjsoncjson
  • 【Manus第三篇-Prompt优化】两周实战,一套注意力视角的prompt优化框架,真的有用!
  • 安装VSCode的时候没勾选将“通过Code打开”操作添加到Windows资源管理器目录上下文菜单(右键VSCODE打开)
  • 计算机视觉课程笔记-机器学习中典型的有监督与无监督学习方法的详细分类、标签空间性质、解释说明,并以表格形式进行总结
  • WebFuture:模板如何加上简繁切换?
  • Vue3+TypeScript中v-bind()的原理与用法
  • 【Docker基础】Docker核心概念:命名空间(Namespace)之User详解
  • 66、【OS】【Nuttx】【构建】System.map文件生成(上)
  • 1572. 矩阵对角线元素的和
  • DELL R730XD服务器调整风扇转速
  • [linux] ftp上传文件
  • 深圳市龙华区网站建设/论坛推广的步骤
  • 通过模版做网站/今日国际新闻事件
  • wordpress怎么查看域名/深圳seo优化电话
  • thinkphp做网站后台/表白网站制作
  • wordpress托管建站/百度官网app
  • 网站建设中企动力推荐/seo网络推广知识