uuid->学号
	在数据传输的过程中,一般不能使用真实的学号,或者姓名id,在数据库的存储过程中,一般也不是简单的ID自增形式,所以使用uuid和姓名或者学号的对应关系。
| 12
 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 = 某个人的项目信息 
| 12
 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函数即可
| 12
 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建的随意字段相互关联了。