V2
关联查询
// usertype TbUser struct {dbUtils.FieldsModelID uint `gorm:"primarykey"`CompanyID intName stringTag stringAge int}type TbCompany struct {dbUtils.FieldsModelAddress stringName string}type TbCard struct {ID uint `gorm:"primarykey"`UserID uintNumber int}type TbLanguage struct {ID uint `gorm:"primarykey"`Name string}// 当使用 GORM 的 AutoMigrate 为 User 创建表时,GORM 会自动创建连接表。这里只是展示type TbUserLanguage struct {LanguageId uintUserId uint}type FieldsModel struct {ID uint `gorm:"primarykey"`CreatedAt int64 `gorm:"autoCreateTime:milli;type:bigint(13);unsigned;comment:创建时间" json:"created_at"`UpdatedAt int64 `gorm:"autoUpdateTime:milli;type:bigint(13);unsigned;comment:修改时间" json:"updated_at"`DeletedAt soft_delete.DeletedAt `gorm:"type:bigint(13);unsigned;comment:删除时间" json:"deleted_at"`}
// 一个用户属于一个公司// user.company_id -> company.idfunc TestPageParamBelongsTo(t *testing.T) {type User struct {TbUserCompany TbCompany}res := &[]User{}err := DB.Preload(clause.Associations).Find(res).Errorfmt.Println(err)}
// 一个用户有一张唱片// user.id -> card.user_idfunc TestPageParamHasOne(t *testing.T) {type User struct {TbUserCard TbCard}res := &[]User{}err := DB.PreloadAll().Find(res).Errorfmt.Println(err)}
// 一个用户有多张唱片// user.id -> []card.user_idfunc TestPageParamHasMany(t *testing.T) {type User struct {TbUserCard []TbCard}res := &[]User{}err := DB.PreloadAll().Find(res).Errorfmt.Println(err)}
// `user_languages` 是连接表func TestPageParamManyToMany(t *testing.T) {type Language struct {TbLanguageUsers []*TbUser `gorm:"many2many:user_languages;"`}type User struct {TbUserLanguages []*Language `gorm:"many2many:user_languages;"`}// 正向: 一个人会多种语言 user <- []language// user.id -> user_languages.user_id,[]language_id -> language.idfunc() {res := &[]User{}err := DB.PreloadAll().Find(res).Errorfmt.Println(err)}()// 反向: 一群人会一种语言 language <- []user// language.id -> user_languages.language_id,[]user_id -> user.idfunc() {res := &[]Language{}err := DB.PreloadAll().Find(res).Errorfmt.Println(err)}()}
Preload 预加载
加载层级
层级递归查询
例 公司部门下属,家庭父子关系。
// 一个iss:https://github.com/go-gorm/gorm/issues/4027// 官方递归:https://gorm.io/docs/has_many.html#Self-Referential-Has-Manytype Person struct {ID string `gorm:"type:uuid;primaryKey;default:gen_random_uuid()" form:"id" json:"id"`Name string `json:"name"`ParentID *string `json:"parent_id" gorm:"type:uuid"`Children []Person `gorm:"foreignKey:ParentID" json:"children"`}func TestChildren(t *testing.T) {// 注意:ParentID 是 `*string` 类型,查询没有问题。// 关联添加的时候必须给指针类型(非指针插入会报错),使用指针会关联插入。data := Person{Name: "a1",Children: []Person{{Name: "a2",Children: []Person{{Name: "a3",},},},},}DB.Create(&data)var result Person// 第一个 Preload 加载其他的关联// 第二个 Preload 加载 Children 的关系DB.Preload(clause.Associations).Preload("Children." + clause.Associations).Find(&result)}
运行结果
// INSERT INTO "person" (name, parent_id) VALUES ("a1", "");// INSERT INTO "person" (name, parent_id) VALUES ("a2", "da185c9c-1717-4720-9fd3-4cc26fc2659d");// INSERT INTO "person" (name, parent_id) VALUES ("a3", "e1cea70b-6eb4-4b83-8500-7a87a65c5fd1");// 这个是倒叙的// SELECT * FROM "person" WHERE "person"."parent_id" = 'e1cea70b-6eb4-4b83-8500-7a87a65c5fd1'// SELECT * FROM "person" WHERE "person"."parent_id" = 'da185c9c-1717-4720-9fd3-4cc26fc2659d'// SELECT * FROM "person"
相关社区
- go-gorm/datatypes - 支持 json、jsonMap、date类型。
``go type Available struct { Use booljson:”use”Reason stringjson:”reason”` }
// Scan scan value into Jsonb, implements sql.Scanner interface func (a *Available) Scan(value interface{}) error { json return nil }
func (a Available) Value() (driver.Value, error) {
return fmt.Sprintf((%t,"%s"), a.Use, a.Reason), nil
}
- [pq](https://github.com/lib/pq) - `BoolArray` `ByteaArray` `Float32Array` `Int32Array` `StringArray` `GenericArray 自定义类型数组` 等等数组类型。帮助我们使用 postgreSQL 的数据类型。```go// 使用 GenericArray 完成 []AvailableArray 结构type AvailableArray []Availablefunc (a *AvailableArray) Scan(src interface{}) error {return pq.GenericArray{A: a}.Scan(src)}func (a AvailableArray) Value() (driver.Value, error) {if a == nil {return "{}", nil}return pq.GenericArray{A: a}.Value()}func (a AvailableArray) MarshalJSON() ([]byte, error) {res := make([]Available, 0)if a != nil {res = a}return json.Marshal(res)}
- gorm-extra-clause-plugin - 支持 postgreSQL 的 WITH (CTE)语法。
V1 已过时
文档:官方、中文文档、tag 介绍
注意:以下是一些需要特别注意的:
debug:
// 启用Logger,显示详细日志db.LogMode(true)// 禁用日志记录器,不显示任何日志db.LogMode(false)// 调试单个操作,显示此操作的详细日志db.Debug().Where("name = ?", "jinzhu").First(&User{})
事务:
// 开始事务tx := db.Begin()// 在事务中做一些数据库操作(从这里必须使用'tx',而不是'db')tx.Create(...)// ...// 发生错误时回滚事务tx.Rollback()// 或提交事务tx.Commit()
