Gorm for SQL Join 关联查询

2019-10-25  本文已影响0人  坚果jimbowhy

Gorm for SQL Join 关联查询

Belongs To: http://gorm.io/docs/belongs_to.html
Has One: http://gorm.io/docs/has_one.html
Has Many: http://gorm.io/docs/has_many.html
Many To Many: http://gorm.io/docs/many_to_many.html
Associations: http://gorm.io/docs/associations.html
Preloading (Eager Loading): http://gorm.io/docs/preload.html

参考官方文档关于 Associations 的部分,连表关系分成 Belongs To、 Has One、 Has Many、 Many To Many、 Associations 几种。

定义了一个 User 和 Company, User 中可以包含多个 Company, 如下:

type User struct {
    ID        int        `gorm:"TYPE:int(11); NOT NULL; PRIMARY_KEY; INDEX"`
    Name      string     `gorm:"TYPE: VARCHAR(255); DEFAULT:'';INDEX"`
    Companies []Company  `gorm:"FOREIGNKEY:UserId; ASSOCIATION_FOREIGNKEY:ID"`
}

type Company struct {
    gorm.Model
    Industry int    `gorm:"TYPE:INT(11);DEFAULT:0"`
    Name     string `gorm:"TYPE:VARCHAR(255);DEFAULT:'';INDEX"`
    Job      string `gorm:"TYPE:VARCHAR(255);DEFAULT:''"`
    UserId   int    `gorm:"TYPE:int(11);NOT NULL;INDEX"`
}

ASSOCIATION_FOREIGNKEY 指定本主表字段名作为关联外键,此关联外键字段与 FOREIGNKEY 指定的外键在连表查询时进行匹配。在查询 User 时希望把 Company 的信息也一并查询, 基本操作通过 Related()、Association()、Preload() 三种方法实现:

Find(&user) 这类方法会返回完整的表字段,包含 select 没有指定的字段置 0 或空字符串,或 Unit 起始时间戳。因为 &user 本身是一个 stuct ,肯定是一个完整的结构,没有值的字段会有默认值,如果不想显示那些的话,可以使用 Scan/ScanRows 等方法:

type Result struct {
  Name string
  Age  int
}

var result Result
db.Table("users").Select("name, age").Where("name = ?", 3).Scan(&result)

// Raw SQL
db.Raw("SELECT name, age FROM users WHERE name = ?", 3).Scan(&result)

扫描 sql.Rows 数据到模型

rows, err := db.Model(&User{}).Where("name = ?", "jinzhu").Select("name, age, email").Rows() // (*sql.Rows, error)
defer rows.Close()

for rows.Next() {
  var user User
  // ScanRows 扫描一行到 user 模型
  db.ScanRows(rows, &user)

  // do something
}

使用 *sql.Row.Scan() 或者 *sql.Rows.Scan() 填充查询结果

row := db.Table("users").Where("name = ?", "jinzhu").Select("name, age").Row() // (*sql.Row)
row.Scan(&name, &age)

rows, err := db.Model(&User{}).Where("name = ?", "jinzhu").Select("name, age, email").Rows() // (*sql.Rows, error)
defer rows.Close()
for rows.Next() {
    ...
    rows.Scan(&name, &age, &email)
    ...
}

// 原生SQL
rows, err := db.Raw("select name, age, email from users where name = ?", "jinzhu").Rows() // (*sql.Rows, error)
defer rows.Close()
for rows.Next() {
    ...
    rows.Scan(&name, &age, &email)
    ...
}
上一篇 下一篇

猜你喜欢

热点阅读