uuid->学号
在数据传输的过程中,一般不能使用真实的学号,或者姓名id,在数据库的存储过程中,一般也不是简单的ID自增形式,所以使用uuid和姓名或者学号的对应关系。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| type LibScore struct { model.Base Name string `gorm:"comment:指标名称"` Tags datatypes.JSONSlice[string] `gorm:"comment:指标标签"` Scope string `gorm:"comment:'指标等级: 系统级 system, 项目级 project/xxx'"` Content []LibScoreContent `gorm:"foreignkey:LibScoreID;"` }
type LibScoreContent struct { model.Base LibScoreID string `gorm:"size:26;index;comment:所属指标id"` StaffId string `gorm:"size:19;comment:用户工号"` Score string `gorm:"comment:指标内容分数/等级"` Extra datatypes.JSON `gorm:"comment:额外信息"` }
type Base struct { ID string `json:"id" gorm:"primary_key;type:char(26)"` CreatedAt time.Time `json:"-"` UpdatedAt time.Time `json:"-"` DeletedAt gorm.DeletedAt `gorm:"index" json:"-"` }
|
这是两张表,LibScore 和 LibScoreContent 一对多的对应关系
类似于 某个项目的成绩->许多人的成绩
我们需要实现查找 某个人的某个项目成绩,顺便返回其他项目的成绩
由于前端传回来的是 uuid ,因此不能获得真正的staffId,需要通过uuid来当桥梁。
因为外键,在LibScoreContent中的 LibScoreID 字段对应的是LibScore的主键(即model.base中的ID),而如何表示某个人呐,就是LibScoreContent中的model.Base.ID(称之为LibContentId)
总结一下就是 uuid = ContentId -> ContentId + scoreId -> staffId + scoreId = 某个人的项目信息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| type LibScoreContentListByStaffIdResponse struct { Total int64 `json:"total"` Detail LibContentDetail `json:"list"` Extra []LibContentDetail `json:"extra"` }
func HandleLibContentDetail(c flamego.Context, r flamego.Render, paginate page.Paginate) { libScoreId := c.Param("id") libContentId := c.Param("contentId") var libContentResponse dto.LibScoreContentListByStaffIdResponse var libContent model.LibScoreContent err := dao.Lib.Model(&model.LibScoreContent{}).WithContext(c.Request().Context()). Where("lib_score_id = ? and id = ?", libScoreId, libContentId). Find(&libContent).Error if err != nil { response.ServiceErr(r, err) return } staffId := libContent.StaffId var count int64 var relatedLibContent []model.LibScoreContent err = dao.Lib.Model(&model.LibScoreContent{}).WithContext(c.Request().Context()). Where("lib_score_id = ? and staff_id = ?", libScoreId, staffId). Scopes(paginate.Paginate()).Find(&relatedLibContent).Offset(-1).Limit(-1).Count(&count).Error
if err != nil { response.ServiceErr(r, err) return } err = copier.Copy(&libContentResponse.Detail, &libContent) if err != nil { response.ServiceErr(r, err) return } err = copier.Copy(&libContentResponse.Extra, &relatedLibContent) if err != nil { response.ServiceErr(r, err) return } libContentResponse.Total = count response.HTTPSuccess(r, libContentResponse) }
|
如何制作uuid
使用Hook函数即可
1 2 3 4
| func (u *User) BeforeCreate(*gorm.DB) error { u.Id = ulid.Make().String() return nil }
|
这样子就能每个人都能有专属的ID了
[]string形式存储数据库
我们发现 []string形式的数据无法存入GORM数据库
用下面的形式来代替
1
| Tags datatypes.JSONSlice[string] `gorm:"comment:指标标签"`
|
外键和主键
主键
是能确定一条记录的唯一标识,比如,一条记录包括身份正号,姓名,年龄。身份证号是唯一能确定你这个人的,其他都可能有重复,所以,身份证号是主键。
实际上,主键除了惟一地标识一行之外,再没有其他的用途了
主键应当有计算机自动生成。如果由人来对主键的创建进行干预,就会使它带有除了惟一标识一行以外的意义。
外键
主键和外键是把多个表组织为一个有效的关系数据库的粘合剂。
A表的外键往往B表的主键
在关系型数据库中,当一张表的外键与另一张表的字段引用其外键时,它们的值通常是相同的
但是上面的示例不一样,上面示例中直接把A表的主键和B建的随意字段相互关联了。