如何在OpenAPI中定义别名以生成适配数据库映射的POJO
OpenAPI生成POJO时如何自定义数据库表和字段别名映射且不修改对外接口定义
假设我在openapi.yml中有如下定义(这只是为了说明我遇到的问题虚构的示例):
components: schemas: Address: type: object properties: name: type: string zip: type: integer format: int64 town: type: string
这会生成如下所示的模型代码:
public class Address { @JsonProperty("name") private String name = null; @JsonProperty("zip") private Long zip = null; @JsonProperty("town") private String town = null; ...
我遇到的问题是,我需要将这个POJO持久化到数据库中,但库中不存在名为Address的表(假设对应的表名为Places),且邮政编码对应的列名为zipcode而非zip。
因此我需要实现两点需求:
- 一种可告知OpenAPI
Address=Places、zip=zipcode别名映射的方式 - 一种可让该别名信息作用于生成代码的方式。以Hibernate为例,就是要在对应位置自动添加
@Table(name="Places")和@Column(name="zipcode")注解。
重要说明:我无法修改API定义,必须保留
Address和zip作为对外的接口字段名。
请问这个需求能否实现?我查阅了OpenAPI 3.1.0规范以及swagger-codegen和openapi-generator(我更倾向使用后者)的相关资料,没有找到该功能的相关支持。针对openapi-generator,我查看了Mustache模板,目前没有发现引用yaml文件中定义的“别名信息”的相关代码。
我是否只能采用自定义方案,自行定义类似OpenAPI扩展,再结合自定义模板来实现需求?我找到的最接近的方案是现有扩展,它可以实现别名定义,但只能满足我第一部分的需求。
解决方案
这个需求完全可以通过你提到的「OpenAPI自定义扩展 + 自定义生成模板」的组合方案实现,具体落地步骤如下:
- 定义专属扩展字段
你可以在OpenAPI的Schema级别和属性级别分别增加自定义扩展,OpenAPI规范允许所有以x-作为前缀的自定义扩展字段,示例配置如下:
components: schemas: Address: x-db-table-name: Places # Schema级扩展,指定对应数据库表名 type: object properties: name: type: string zip: x-db-column-name: zipcode # 属性级扩展,指定对应数据库列名 type: integer format: int64 town: type: string
- 调整OpenAPI Generator的Mustache模板
你只需要复制官方的pojo.mustache模板到你的自定义模板目录,做两处小修改即可:
- 在类定义的上方,增加@Table注解的渲染逻辑:
{{#vendorExtensions.x-db-table-name}} @Table(name = "{{vendorExtensions.x-db-table-name}}") {{/vendorExtensions.x-db-table-name}} public class {{classname}} {
- 在属性定义的上方,增加@Column注解的渲染逻辑:
{{#vendorExtensions.x-db-column-name}} @Column(name = "{{vendorExtensions.x-db-column-name}}") {{/vendorExtensions.x-db-column-name}} @JsonProperty("{{baseName}}") private {{datatype}} {{name}} = null;
- 生成代码时指定自定义模板路径
执行openapi-generator命令时增加-t 你的自定义模板目录参数,生成器就会自动读取你定义的扩展字段,渲染出符合要求的带Hibernate注解的POJO代码,同时完全保留原有的@JsonProperty注解,不会对外暴露数据库相关的别名,满足你不修改对外接口定义的要求。
如果后续需要扩展更多持久化相关的配置(比如主键、索引、字段长度等),只需要对应新增扩展字段和模板渲染逻辑即可,不需要侵入原有的API接口定义。
内容的提问来源于stack exchange,提问作者Marged
相关产品推荐
相关产品推荐

