Gorm 的数据完整性约束、一对一、一对多

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),INDEX idx_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

相关推荐
ldmd2845 小时前
地图生成算法(噪声篇-Perlin,Simplex,Value noise)
算法·go·地图生成
妙码生花6 小时前
从 PHP 到 AI + Golang,程序员自救转型手记(四十一):增加管理员账号管理接口
后端·go·gin
名字还没想好☜2 天前
Go for-range 循环变量陷阱:goroutine 里全打印同一个值(Go 1.22 前后差异)
开发语言·后端·golang·go
光头闪亮亮2 天前
Fyne ( go跨平台GUI )项目实战-项目开发必备基础知识(中)
android·c++·go
光头闪亮亮2 天前
Fyne ( go跨平台GUI )项目实战-项目开发必备基础知识(上)
android·sqlite·go
光头闪亮亮2 天前
Fyne ( go跨平台GUI )项目实战-项目开发必备基础知识(下)
android·c++·go
妙码生花2 天前
从 PHP 到 AI + Golang,程序员自救转型手记(三十六):多驱动上传接口
后端·go·ai编程
golang学习记3 天前
从 CRUD 到生产就绪:Go 后端必须掌握的五个分布式系统模式
go
名字还没想好☜3 天前
Go 结构体内存对齐:调整字段顺序,同样的字段省下 40% 内存
开发语言·后端·golang·go·内存对齐