Golang Go语言中gorm 联合查询的时候如何只查询指定字段?

发布于 1周前 作者 nodeper 来自 Go语言

Golang Go语言中gorm 联合查询的时候如何只查询指定字段?

有如下三个 struct

type Article struct {
	gorm.Model
	CategoryID int            `json:"-" gorm:"not null"`
	Category   Category       `json:"category" gorm:"ForeignKey:CategoryID;`
	Title      string         `json:"title" gorm:"not null;type:varchar(100);"`
	AuthorID   int            `json:"-"`
	Author     Author         `gorm:"ForeignKey:AuthorID"`
	Content    string         `json:"content" gorm:"not null;type:text"`
}
type Category struct {
	ID   uint   `json:"id" gorm:"primary_key;AUTO_INCREMENT"`
	Name string `json:"name" gorm:"type:varchar(100)"`
	Max  int    `json:"max"`
}
type Author struct {
	gorm.Model
	Name string `json:"name"`
}

想实现如下的 SQL 应该如何写呢?

SELECT a.id,a.title,b.name as category,c.name as author FROM article a, category b, author c WHERE a.category_id=b.id AND a. author_id = c.id AND a.category_id =1

// 这样是查询出了三张表的所有字段,Select 好像只支持当前表的字段 // list := []Article{} // mysql.Preload(“Author”).Preload(“Category”).Find(&list, “category_id=?”, 1)


更多关于Golang Go语言中gorm 联合查询的时候如何只查询指定字段?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html

12 回复

gorm 的 perload 不是联合查询吧

gorm.io/docs/sql_builder.html#Run-Raw-SQL 试试这个?

更多关于Golang Go语言中gorm 联合查询的时候如何只查询指定字段?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


Preload 是联合查询的

我现在也的解决方案也是 raw

Custom Preloading SQL
You could custom preloading SQL by passing in func(db *gorm.DB) *gorm.DB, for example:

db.Preload(“Orders”, func(db *gorm.DB) *gorm.DB {
return db.Order(“orders.amount DESC”)
}).Find(&users)
//// SELECT * FROM users;
//// SELECT * FROM orders WHERE user_id IN (1,2,3,4) order by orders.amount DESC;

不知道你们用 gorm 有没有发现 gorm 关联查询有个问题!

比如 user role permission 三个表, user 与 role 是多对多的关系, role 与 permission 是多对多的关系!

如果我想查 模糊查询 user 的 name like test, 然后限定 角色 role = default 的

在 gorm 里用 Preload 会出现两条 sql, 一条是 select * from user where username like %test%

第二条是 select * from role inner join user_role on user_role.role_id = role.id where role.name = default

然后 gorm 会把第二条的数据关联回第一条的结果上!

可是这样跟要求是不一致的!

不知道你们有没有发现这个!

所以真的有这种需求的时候,建议 手写 sql 或者 join

直接写 sql 呀

db.Table(“article a”).Select(“a.id,a.title,b.name as category,c.name as author”).Joins(“left join category b on a.category_id = b.id”).Joins(“left join author c on a.author_id = c.id AND a.category_id =1”).Scan()

是的。简单的用 gorm,复杂的就直接手写 sql 了

手写 sql 有个不好的就是 得写死 表名!

万一改了表名(改表名,换了新表,添加修改前缀等)就得哭!

除非调用 tablename 方法,不过这样就得拼凑字符串了…

在Golang中使用GORM进行联合查询(JOIN)时,如果你只想查询指定字段,可以通过GORM提供的Select方法来实现。Select方法允许你明确指定要查询的字段,这样可以减少数据传输量并提高查询效率。

以下是一个示例,展示了如何在GORM中进行联合查询并只查询指定字段:

package main

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

type User struct {
    ID   uint
    Name string
}

type Profile struct {
    ID      uint
    UserID  uint
    Address string
}

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

    var results []struct {
        UserName string
        Address  string
    }
    db.Table("users").Select("users.name AS user_name, profiles.address").
        Joins("JOIN profiles ON profiles.user_id = users.id").
        Scan(&results)

    for _, result := range results {
        fmt.Printf("User: %s, Address: %s\n", result.UserName, result.Address)
    }
}

在这个例子中,我们使用了Table方法来指定主表,通过Joins方法进行联合查询,然后使用Select方法来指定要查询的字段。最后,通过Scan方法将查询结果映射到一个自定义的结构体中。这样,你就可以在联合查询中只获取你需要的字段了。

回到顶部