美文网首页
Gorm for SQL Join 关联查询

Gorm for SQL Join 关联查询

作者: 坚果jimbowhy | 来源:发表于2019-10-25 12:13 被阅读0次

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() 三种方法实现:

  • 使用 Related 方法, 需要把把 User 查询好, 然后根据 User 中定义的 FOREIGNKEY 指定外键字段名去查找 Company 表中 UserId 匹配的记录, 如果没定义, 则调用 Related(value, foreignKeys) 时需要指定。注意 Related() 和 Find() 一样时立即方法,即会请求数据,如果又添加 Find(&u.Companies) 就是 Multiple Immediate Methods 方式,可能出现逻辑错误,参考 Method Chaining 链式操作。

      var u User
      db.First(&u)
      db.Model(&u).Related(&u.Companies)
    
  • 使用 Association 方法, 需要把把 User 查询好, 然后根据 User 定义中指定的 AssociationForeignKey 去查找 Company, 必须定义。

      var u User
      db.First(&u)
      db.Model(&u).Association("Companies").Find(&u.Companies)
    
  • 使用 Preload 方法, 在查询 User 时先去获取 Company 的记录。

      // 查询单条 user
      var u User
      db.Debug().Preload("Companies").First(&u)
    
      // 对应的 sql 语句
      // SELECT * FROM users LIMIT 1;
      // SELECT * FROM companies WHERE user_id IN (1);
       
      // 查询所有 user
      var users []User
      db.Debug().Preload("Companies").Find(&users)
    
      // 对应的 sql 语句
      // SELECT * FROM users;
      // SELECT * FROM companies WHERE user_id IN (1,2,3...);
    

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)
    ...
}

相关文章

  • Gorm for SQL Join 关联查询

    Gorm for SQL Join 关联查询 Belongs To: http://gorm.io/docs/be...

  • SQL连接查询研究

    1、分类在多表关联查询时,经常要用到连接查询,SQL中连接分为四种:内连接(inner join或join)、左外...

  • 6、SQL优化手段有哪些

    SQL优化手段有哪些 1、查询语句中不要使用select * 2、尽量减少子查询,使用关联查询(left join...

  • 使用logrus记录gorm sql

    gorm可以方便的输出执行的sql或慢查询。logrus是常用的日志组件,如何将gorm输出的sql通过logru...

  • 如何在EF中实现left join(左联接)查询

    在EF中,当在dbset使用join关联多表查询时,连接查询的表如果没有建立相应的外键关系时,EF生成的SQL语句...

  • gorm分页查询count报错 sql: no rows in

    gorm分页查询count报错 sql: no rows in result set 业务重现 注意,Count(...

  • Sql之join多种用法

    sql优化中常用的就是将表关联或子查询改为join的用法,那么join的用法有很多种,下面我们一一看下。参考:ht...

  • 连接查询

    SQL表连接查询(inner join、full join、left join、right join) 有两个表,...

  • MySQL中的join以及on条件的用法

    join 经常用来做关联查询,可以把两张或者多张表用通过关联条件关联起来做数据查询在使用join查询的时候要区分主...

  • GORM 关联查询

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

网友评论

      本文标题:Gorm for SQL Join 关联查询

      本文链接:https://www.haomeiwen.com/subject/yrjsvctx.html