GORM 高级使用
「一对多」关系
显性声明一对多关系
- 字段类型为嵌套[]struct
- 是否需要显性声明一对多关系,
需要
。否则会报错
[error] invalid field found for struct x.com/dto/xBillDetail's field ComponentSet: define a valid foreign key for relations or implement the Valuer/Scanner interface
示例
tag;定义
ForeignKey
,指向子表的BillDetailID字段
go
type QCloudBillDetail struct {
gorm.Model
ComponentSet []QCloudBillDetailComponent `json:"componentSet,omitempty" name:"ComponentSet" gorm:"ForeignKey:BillDetailID"`
Tags []QCloudBillTagInfo `json:"tags,omitempty" name:"Tags" gorm:"ForeignKey:BillDetailID"`
PriceInfo QCloudPriceInfo `json:"priceInfo,omitempty" name:"PriceInfo" gorm:"type:json"`
}
ComponentSet
字段 嵌套ComponentSet列表
,需要指定ComponentSet的ID为主键- 未指定主键,会报错
- [error] invalid field found for struct acmp-service/dto.XBillDetail's field ComponentSet: define a valid foreign key for relations or implement the Valuer/Scanner interface
- 解决:增加主键
- Tags字段 处理相同;增加主键
一对多 子表的主键设置
go
type QCloudBillDetailComponent struct {
gorm.Model
BillDetailID int64 `json:"billDetailID,omitempty" name:"BillDetailID" gorm:"type:varchar(16)"`
}
go
type QCloudBillTagInfo struct {
gorm.Model
BillDetailID int64 `json:"billDetailID,omitempty" name:"BillDetailID" gorm:"type:varchar(16)"`
}
「一对多」的另外一种形态[]string
- PriceInfo字段;grom支持[]struct,也支持[]string;但不支持[]*string指针
- 使用[]*string,会报错
- got error unsupported data type: &[]
- 解决:要么使用[]string;要么转换为[]struct
- 且如果要使用[]string,是支持的,但
- 需要创建实现 Valuer/Scanner 接口的自定义数据类型
通过实现Value、Scan方法
go
import (
"database/sql/driver"
)
type XPriceInfo []string
func (s XPriceInfo) Value() (driver.Value, error) {
// 序列化 `Strings` 为 JSON 字符串
jsonString, err := json.Marshal(s)
if err != nil {
return nil, err
}
// 返回 JSON 字符串
return jsonString, nil
}
func (s *XPriceInfo) Scan(value interface{}) error {
// 反序列化 JSON 字符串为 `Strings`
jsonString, ok := value.([]byte)
if !ok {
return errors.New("invalid type")
}
err := json.Unmarshal(jsonString, s)
if err != nil {
return err
}
return nil
}
[]string类型,在数据库类型为json
json类型字段
- json类型字段,是否需要约束json字段长度。
不能限定
,否则会报错PriceInfo QCloudPriceInfo
json:"priceInfo,omitempty" name:"PriceInfo" gorm:"type:json"``
Error 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '(32),PRIMARY KEY (
id
),INDEXidx_q_cloud_bill_details_deleted_at
(`deleted_at' at line 1
声明grom类型json
- PriceInfo字段指向 QCloudPriceInfo
go
PriceInfo QCloudPriceInfo `json:"priceInfo,omitempty" name:"PriceInfo" gorm:"type:json"`
「一对一」关系
字段为自定义类型 如struct
golang
AssociatedOrder QCloudBillDetailAssociatedOrder `json:"associatedOrder,omitempty" name:"AssociatedOrder"`
go
type QCloudBillDetailAssociatedOrder struct {
gorm.Model
BillDetailID int64 `json:"billDetailID,omitempty" name:"BillDetailID" gorm:"type:varchar(16)"`
PrepayPurchase string `json:"prepayPurchase,omitempty" name:"PrepayPurchase" gorm:"type:varchar(16)"`
PrepayRenew string `json:"prepayRenew,omitempty" name:"PrepayRenew" gorm:"type:varchar(16)"`
PrepayModifyUp string `json:"prepayModifyUp,omitempty" name:"PrepayModifyUp" gorm:"type:varchar(16)"`
ReverseOrder string `json:"reverseOrder,omitempty" name:"ReverseOrder" gorm:"type:varchar(16)"`
NewOrder string `json:"newOrder,omitempty" name:"NewOrder" gorm:"type:varchar(16)"`
Original string `json:"original,omitempty" name:"Original" gorm:"type:varchar(16)"`
}
struct类型,在数据库类型为longblob