You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go 1.17使用Sqlx关联同名字段表时ID被覆盖如何解决

问题根因

sqlx做结构体映射时,会按照查询返回的列顺序,匹配结构体字段的db标签(没有标签则匹配字段名小写)赋值,你使用SELECT *做联表查询时,两张表的id、title字段名重复,后返回的movie表字段值会覆盖Album结构体对应字段的值。

解决方案

两种常用方案可以解决这个问题:

  • 方案1:显式指定查询字段,给嵌入结构体字段加别名
    放弃SELECT *写法,明确列出需要查询的字段,跳过不需要的movie表id字段,同时给和Album重名的movie字段加movie.前缀别名,sqlx会自动将该类字段映射到内嵌的Movie结构体中,示例代码如下:

    albums := []Album{}
    sql := `
    SELECT 
      a.id, a.title, a.artist, a.price, a.movie_id,
      m.year, m.rent_number, m.title as "movie.title",
      m.author, m.editor, m.index, m.bib, m.ref, m.cat_1, m.cat_2
    FROM album a INNER JOIN movie m ON m.id = a.movie_id
    `
    if err := r.db.Select(&albums, sql); err != nil {
      // 错误处理逻辑
    }
    

    这种方案不需要修改原有结构体定义,适合临时做联表查询的场景。

  • 方案2:给内嵌结构体加db前缀标签
    先修改Album结构体,给内嵌的Movie字段加db标签指定统一前缀:

    type Album struct {
        ID      string  `json:"id"`
        Title   string  `json:"title"`
        Artist  string  `json:"artist"`
        Price   float64 `json:"price"`
        MovieId int     `json:"movie_id" db:"movie_id"`
        // 指定内嵌结构体所有字段的映射前缀
        Movie   movie.Movie `db:"movie_"`
    }
    

    写查询SQL时给所有movie表的字段加对应前缀的别名,同样跳过movie的id字段即可:

    albums := []Album{}
    sql := `
    SELECT 
      a.id, a.title, a.artist, a.price, a.movie_id,
      m.year as movie_year,
      m.rent_number as movie_rent_number,
      m.title as movie_title,
      m.author as movie_author,
      m.editor as movie_editor,
      m.index as movie_index,
      m.bib as movie_bib,
      m.ref as movie_ref,
      m.cat_1 as movie_cat_1,
      m.cat_2 as movie_cat_2
    FROM album a INNER JOIN movie m ON m.id = a.movie_id
    `
    if err := r.db.Select(&albums, sql); err != nil {
      // 错误处理逻辑
    }
    

    这种方案字段映射更清晰,适合多场景频繁使用该关联结构体查询的场景。

注意事项

联表查询时尽量不要使用SELECT *写法,显式指定字段不仅可以避免字段覆盖问题,也能减少不必要的字段查询,提升查询效率。

内容的提问来源于stack exchange,提问作者John

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 05:15:08