代码生成器原理

00:33

1
2
SHOW TABLE STATUS FROM order_center;
SHOW FULL COLUMNS FROM order_item;
  1. 第一句执行后,会将数据库下所有表都列出来,拿出指定的一行,将来转换成 Entity
  2. 第二句执行后,会将每个表中的属性详情查找出来

01:59

最简单的实现方式:数据库 -> 模板引擎。

可以通过 IDE 的 Live Template 实现。

03:55

DTO 代表的是前端的输入/输出,Entity 代表的是库表映射对象,简单的代码生成器只能应付 Entity 的情景(例如,is_deleted 字段显然不适合透传给前端),我们按照上面的方法生成的对象不可能直接对应到 DTO,也就是说,只能生成针对 DAO 层的东西。

如果只是单纯的减少某些变量,还是可以通过这种方法来处理,这里我们可以生成 Request 对象。

06:06

有些带页面的代码生成器会针对 Field 进行一些配置,例如增加一些校验规则。

对于面向数据库增删改查,这种操作已经足够了。但是,对于扩展性比较高的项目,这种方法有很大局限性。

07:04

Mybatis 最痛苦的一点是数据库的某些字段增减时,维护 Mapper 需要进行很多重复的工作。

JPA 封装了对数据库操作的抽象,也封装了对领域对象的抽象。

JPA 可以让我们不关心数据库,而是关心对象的建模,也就是说,根据对象的建模,把相应的 Mapper、Request 等对象都生成出来。

09:42

我们不把 DTO 对象命名为 DTO。

我们把 DTO 对象划分为 Request 和 Response 对象。

对数据库每张表的操作,我们把它们划分为 Creator 和 Updater 对象。

为了解决 Mabatis 增减对象时每次频繁修改对象,让数据表的状态更改只能通过 Service 方法进行,这样的好处是维护点的统一,将来能跟踪到任何一次状态的跟踪。

14:28

VO 的操作只能对应单表的数据,Response 可能对应多个 VO。

Request 和 Response 的定位是产品层。

VO 通常是固定的,而 Respose 是动态配置的。

这里插一点我的见解,作者的意思可能是我先写一个 Entity,其他的所有对象都通过 Entity 生成,当库表接口变化时,或者业务需求变化时,我只需要修改 Entity 类,比如在某些字段上添加注解,之后再通过代码生成器生成其他业务代码。

18:58

Request 对象可能分为两部分信息(个人信息和地址信息)。

Request 信息需要转换成 creator 对象(requestToCreator 方法)。

20:11

对于微服务而言,我们还需要生成 Feign、Controller。

21:30

MapStruct 通过 APT 来在编译器解析。

class 类型,通过注解拿到。

26:20

根据拿到的元信息,可以通过 JavaPoet 工具包生成类。

auto-service 工具包会自动生成 SPI,如果没有工具包,需要根据 APT 的规范写。

28:16

这个时候需要考虑如何去做一个复用。

我未来需要增加一个生成的类。

我就想生成代码,这时候需要定义一个接口。

  1. 处理哪个注解标记的类
  2. 生成到哪里
  3. 拿到 class 你要做什么,生成逻辑 JavaScript

可以通过 SPI,来实现上面的功能。

32:57

Service 的生成可能就比较复杂一点。

这时候需要抽象出一个概念,Service 生成代码会依赖很多类。

如果注解之上没有这些东西,会生成失败。

生成的时候,会把所有类上的注解放到上下文中。

35:39

Registery 的概念相当于把 Processor 加载出来放在一个注册中心中去,并存在一个地方。