gin-vue-admin Model 层开发指南:GORM 实体定义、标签规范与字段类型约定
2026/9/20 22:28:56 网站建设 项目流程

gin-vue-admin Model 层开发指南:GORM 实体定义、标签规范与字段类型约定

【免费下载链接】gin-vue-admin🚀Vite+Vue3+Gin的开发基础平台,支持TS和JS混用。它集成了JWT鉴权、权限管理、动态路由、显隐可控组件、分页封装、多点登录拦截、资源权限、上传下载、代码生成器【可AI辅助】、表单生成器和可配置的导入导出等开发必备功能。项目地址: https://gitcode.com/flipped-aurora/gin-vue-admin

导读

本文面向在 gin-vue-admin 项目中新增或修改数据库实体的开发者(包括 AI 辅助编码场景),系统讲解后端server/model/**目录下数据模型(Model)的编写规范。你将掌握global.GVA_MODEL基类的继承方式、jsongorm双标签的使用约定、关联关系的声明方法、字段命名与类型一致性要点,并结合仓库中的真实模型文件(如sys_api_token.gosys_user.go)获得可直接照抄的实战写法。

背景:Model 在分层架构中的定位

gin-vue-admin 后端采用经典的分层结构:router → api → service → model,其中Model 负责定义数据库实体与持久化字段,是 Service 与数据库交互的基础。项目目录划分见 server/model,主要包含三块:

  • server/model/system:系统核心实体(用户、角色、菜单、API、字典、操作记录等);
  • server/model/example:示例业务实体(客户、文件上传下载等),也是代码生成器的参考样板;
  • server/model/common:公共基类型,如JSONMapJSONSlice等自定义字段类型。

当你需要新增一张业务表、为现有表补字段、或定义 GORM 结构与关联关系时,就应当遵循本文介绍的写法。这也是 aiDoc/examples/backend 中约定的后端分层示例之一(其余还有 request、service、api、router、enter.go 等示例,见 model-example.md)。

一、什么时候应该写 Model 文件

根据 model-example.md 的约定,以下场景需要在server/model/**中新增或修改代码:

  • 新增一张业务表:定义全新的持久化实体,对应数据库中的一张新表;
  • 为现有表补字段:在已有实体上扩展持久化字段;
  • 需要定义 GORM 结构与关联关系:声明一对一、一对多、多对多关系,或需要定制表名、索引、默认值等。

注意:仅用于请求参数校验、或仅用于接口展示(如列表视图 DTO)的数据,不应直接塞进数据库 model,而是放在对应的request/response包中(如 server/model/system/request 与 server/model/system/response)。

二、推荐写法示例

model-example.md 给出了一个最小可用的订单模型示例:

package system import "github.com/flipped-aurora/gin-vue-admin/server/global" type Order struct { global.GVA_MODEL Name string `json:"name" gorm:"comment:订单名称"` Status int `json:"status" gorm:"default:1;comment:订单状态"` Remark string `json:"remark" gorm:"comment:备注"` CreatorID uint `json:"creatorId" gorm:"comment:创建人ID"` }

几个关键点:

  • 结构体命名为Order,对应表名默认是复数蛇形形式orders
  • 首行嵌入global.GVA_MODEL,自动获得主键与时间字段;
  • 每个业务字段必须同时带json标签(接口输出用)与gorm标签(字段约束用);
  • 布尔、枚举类字段建议声明默认值,如default:1

三、为什么这样写:标签背后的原理

3.1 继承global.GVA_MODEL基类

global.GVA_MODEL定义在 server/global/model.go:

type GVA_MODEL struct { ID uint `gorm:"primarykey" json:"ID"` // 主键ID CreatedAt time.Time // 创建时间 UpdatedAt time.Time // 更新时间 DeletedAt gorm.DeletedAt `gorm:"index" json:"-"` // 删除时间 }

继承它带来的效果:

  • 主键风格统一IDuint自增主键,所有表主键命名一致;
  • 时间字段统一:自动获得CreatedAtUpdatedAt,GORM 会自动维护;
  • 软删除开箱即用DeletedAt gorm.DeletedAt实现了 GORM 软删除——删除操作变为逻辑删除(写入删除时间),查询时自动过滤已删除记录,且该字段通过json:"-"隐藏,不会出现在接口输出中。

从源码结构看,几乎所有业务实体(sys_api_token.go、exa_customer.go 等)都以嵌入global.GVA_MODEL开头,这是项目内最强的一致性原则。

3.2json标签:前后端字段契约

json标签决定结构体序列化为 JSON 时的字段名,是前端接口契约。例如sys_api_token.go中:

UserID uint `json:"userId" gorm:"comment:用户ID"` AuthorityID uint `json:"authorityId" gorm:"comment:角色ID"`

前端拿到的字段就是userIdauthorityId(驼峰命名),而 Go 源码中则是UserIDAuthorityID(大驼峰)。两者通过标签解耦,因此:

  • 字段命名要清晰、稳定,避免随意改名造成前端联动修改;
  • 同一字段在前后端必须使用相同语义的命名(如userId就统一用userId),这正是 model-example.md 强调的"字段命名尽量清晰、稳定,便于前后端保持一致"。

3.3gorm标签:字段级数据库约束

gorm标签用于约束字段类型、默认值和注释。常见用法汇总(均来自仓库真实代码):

用法示例含义
字段注释gorm:"comment:订单名称"生成表结构时写入字段注释
默认值gorm:"default:1;comment:订单状态"插入时未指定则取默认值
类型指定gorm:"type:text;comment:Token"强制指定数据库列类型(长文本等)
索引gorm:"index;comment:用户UUID"为该字段建普通索引
唯一gorm:"not null;unique;primary_key"非空 + 唯一(如角色 ID,见 sys_authority.go)
外键gorm:"foreignKey:UserID"声明关联外键
多对多gorm:"many2many:sys_user_authority;"声明连接表
内嵌结构gorm:"embedded"将子结构字段扁平化嵌入本表
忽略字段gorm:"-"不映射数据库列(仅用于内存计算/展示)

参考实例:sys_user.goHeaderImgdefault:https://...(头像默认值)、AuthorityIddefault:888sys_operation_record.goAgentBodyResp使用type:text存放可能较长的内容。

四、进阶:关联关系与自定义字段

4.1 外键关联(belongs to / has many)

server/model/system/sys_api_token.go 展示了外键关联的标准写法:

type SysApiToken struct { global.GVA_MODEL UserID uint `json:"userId" gorm:"comment:用户ID"` User SysUser `json:"user" gorm:"foreignKey:UserID;"` AuthorityID uint `json:"authorityId" gorm:"comment:角色ID"` Token string `json:"token" gorm:"type:text;comment:Token"` Status bool `json:"status" gorm:"default:true;comment:状态"` // true有效 false无效 ExpiresAt time.Time `json:"expiresAt" gorm:"comment:过期时间"` Remark string `json:"remark" gorm:"comment:备注"` }

要点:

  • 同时保留外键字段UserID和关联字段User SysUser,通过gorm:"foreignKey:UserID"绑定;
  • SysUser类型来自同包定义(sys_user.go),跨包引用时需显式 import(见 exa_customer.go 中对system.SysUser的引用);
  • 关联字段也带json标签,方便接口输出嵌套用户信息。

4.2 多对多与自关联

server/model/system/sys_user.go 演示了多对多(用户 ↔ 角色):

Authorities []SysAuthority `json:"authorities" gorm:"many2many:sys_user_authority;"`

连接表sys_user_authority由 GORM 自动维护,无需手动建实体。

server/model/system/sys_dictionary.go 演示了一对多自关联(父字典 → 子字典):

ParentID *uint `json:"parentID" gorm:"column:parent_id;comment:父级字典ID"` Children []SysDictionary `json:"children" gorm:"foreignKey:ParentID"`

注意父字段用*uint(允许为空表示顶级节点),并用column:parent_id显式指定列名以保持蛇形命名。同样的自关联模式也出现在 sys_dictionary_detail.go。

4.3 自定义表名

默认表名由 GORM 根据结构体名推导(复数蛇形)。需要定制时实现TableName()方法,例如 sys_user.go:

func (SysUser) TableName() string { return "sys_users" }

server/model/system/sys_api.go 同样通过该方法将SysApi映射到sys_apis。这是保持系统内表名命名统一(复数、蛇形)的可靠手段。

4.4 JSON 类型字段(公共基类型)

gin-vue-admin 在 server/model/common/basetypes.go 中提供了可直接使用的 JSON 字段类型:

  • JSONMapmap[string]any,序列化为 JSON 列;
  • JSONSlice[T]:泛型切片,如[]string[]int

它们实现了driver.Valuer/sql.Scanner,并会根据方言自动选择数据库列类型:MySQL 为JSON(旧版/ MariaDB 回退LONGTEXT)、PostgreSQL 为JSONB。使用示例见 sys_user.go 中的OriginSetting common.JSONMap字段,搭配gorm:"type:text;default:null;column:origin_setting;comment:配置;"使用。

五、常见错误清单(务必规避)

model-example.md 明确列出了以下高频问题:

  1. 缺少jsongorm标签:字段将无法正确输出到接口或无法生成合理的表结构;
  2. 把仅用于请求或展示的字段直接写入数据库 model:应放入request/response包,避免污染表结构(如按钮权限等只读计算字段在sys_dictionary_detail.go中用gorm:"-"排除);
  3. 同一个字段在前后端使用不同类型:前端userId为字符串、后端却定义为uint,会导致类型不匹配与隐性 bug;
  4. 忽略StatusID、时间字段这类高风险类型一致性问题ID统一用uint、状态字段统一用int/bool、时间统一用time.Time,并尽量使用global.GVA_MODEL继承的字段,避免重复定义主键与时间字段造成风格分裂。

六、真实参考文件

以下是仓库中可直接参考的成熟 Model 文件,建议在动手前逐一对照:

  • server/model/system/sys_api_token.go:外键关联 +type:text长文本 + 默认值 + 时间字段的完整示例;
  • server/model/system/sys_user.go:多对多、索引、默认值、TableName()common.JSONMap综合示例;
  • server/model/system/sys_base_menu.go:gorm:"embedded"内嵌子结构、多对多、gorm:"-"忽略字段示例;
  • server/model/system/sys_authority.go:自定义主键(primary_key)与not null;unique约束示例;
  • server/model/system/sys_operation_record.go:time.Durationtype:text、关联用户字段示例;
  • server/model/example/exa_customer.go:跨包引用system.SysUser的示例业务实体。

结语

Model 层是 gin-vue-admin 后端数据链路的基石。遵循本文约定——统一继承global.GVA_MODEL、为每个持久化字段同时声明jsongorm标签、按需声明关联关系与自定义表名、保持字段命名与类型的前后端一致——就能让新增的业务表与既有系统风格完全对齐,也能让 AI 辅助生成的后端代码与人工代码无缝衔接,减少后续维护成本。

【免费下载链接】gin-vue-admin🚀Vite+Vue3+Gin的开发基础平台,支持TS和JS混用。它集成了JWT鉴权、权限管理、动态路由、显隐可控组件、分页封装、多点登录拦截、资源权限、上传下载、代码生成器【可AI辅助】、表单生成器和可配置的导入导出等开发必备功能。项目地址: https://gitcode.com/flipped-aurora/gin-vue-admin

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询