MST

星途 面试题库

面试题:Go的GORM如何处理复杂的关联关系查询

假设有两个结构体`Author`和`Book`,一个`Author`可以有多个`Book`,使用GORM建立这种一对多关系。现在需要查询出所有有至少3本书的作者信息,包括作者名以及对应的书的数量,给出具体的GORM查询代码及必要说明。
45.8万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试
package main

import (
    "gorm.io/driver/sqlite"
    "gorm.io/gorm"
)

// Author 作者结构体
type Author struct {
    ID    uint
    Name  string
    Books []Book
}

// Book 书籍结构体
type Book struct {
    ID     uint
    Title  string
    AuthorID uint
}

func main() {
    db, err := gorm.Open(sqlite.Open("test.db"), &gorm.Config{})
    if err != nil {
        panic("failed to connect database")
    }

    // 自动迁移表
    db.AutoMigrate(&Author{}, &Book{})

    // 查询所有有至少3本书的作者信息
    var authors []struct {
        Name  string
        BookCount int
    }
    db.Model(&Author{}).
        Select("authors.name, COUNT(books.id) as book_count").
        Joins("JOIN books ON authors.id = books.author_id").
        Group("authors.id").
        Having("COUNT(books.id) >= 3").
        Scan(&authors)

    // 打印结果
    for _, author := range authors {
        println(author.Name, author.BookCount)
    }
}

说明

  1. 定义了AuthorBook两个结构体,通过在Author结构体中嵌入Books []Book来建立一对多关系。
  2. 使用gorm.Open连接SQLite数据库,并使用AutoMigrate自动迁移表结构。
  3. 使用db.Model(&Author{})指定从Author表开始查询。
  4. Select指定需要查询的字段,包括作者名和书的数量(使用别名book_count)。
  5. Joins通过JOIN语句连接books表,关联条件是authors.id = books.author_id
  6. Groupauthors.id进行分组。
  7. Having过滤出拥有至少3本书的作者,COUNT(books.id) >= 3表示书的数量至少为3。
  8. 最后使用Scan将查询结果扫描到authors切片中。