Golang中Gorm的select where查询失效问题排查

Golang中Gorm的select where查询失效问题排查 我需要使用Gorm执行一个查询。 这个查询:SELECT * FROM sessionusernames WHERE username = 'Erwan'; 它给出了这个结果:1|2018-11-25 19:16:10.993609942+01:00|2018-11-25 19:16:10.993609942+01:00|2018-11-25 19:16:11.21314659+01:00|Erwan|mszpxWpUx4uQsCTxrvBbmJdvUoh3 这正是我想要的!

我这样做了:

type Sessionusername struct {
	gorm.Model
	Username string `gorm:"not null;unique"`
	Token    string
}

var session Sessionusername
db.Table("sessionusernames").Where("username = ?", "Erwan").First(&session)
if (Sessionusername{}) == session {
  println("Empty")
}

但是session是空的 你有什么想法吗?


更多关于Golang中Gorm的select where查询失效问题排查的实战教程也可以访问 https://www.itying.com/category-94-b0.html

2 回复

也许我应该使用 SQL 删除而不是 Gorm 软删除

更多关于Golang中Gorm的select where查询失效问题排查的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在GORM中,当查询结果为空时,First方法不会返回错误,而是会设置一个零值结构体。你的代码中检查空值的方式有问题,而且可能还存在其他配置问题。

以下是几种排查和解决方案:

1. 正确的空值检查方式

type Sessionusername struct {
    gorm.Model
    Username string `gorm:"not null;unique"`
    Token    string
}

var session Sessionusername
result := db.Table("sessionusernames").Where("username = ?", "Erwan").First(&session)

// 正确的空值检查方式
if result.Error != nil {
    if errors.Is(result.Error, gorm.ErrRecordNotFound) {
        println("Record not found")
    } else {
        println("Error:", result.Error.Error())
    }
} else if session.ID == 0 {
    println("Empty record")
} else {
    println("Found:", session.Username)
}

2. 使用Debug模式查看实际执行的SQL

var session Sessionusername
result := db.Debug().Table("sessionusernames").Where("username = ?", "Erwan").First(&session)
fmt.Printf("SQL: %v\n", result.Statement.SQL.String())

3. 检查表名映射问题

GORM默认使用结构体名的复数形式作为表名,确保表名正确:

// 方式1:明确指定表名
var session Sessionusername
db.Table("sessionusernames").Where("username = ?", "Erwan").First(&session)

// 方式2:使用结构体默认表名
var session Sessionusername
db.Where("username = ?", "Erwan").First(&session)

// 方式3:自定义表名
func (Sessionusername) TableName() string {
    return "sessionusernames"
}

var session Sessionusername
db.Where("username = ?", "Erwan").First(&session)

4. 完整的排查示例

type Sessionusername struct {
    gorm.Model
    Username string `gorm:"not null;unique"`
    Token    string
}

func main() {
    // 确保数据库连接正常
    dsn := "user:password@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local"
    db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
    if err != nil {
        panic("failed to connect database")
    }

    var session Sessionusername
    
    // 使用Debug模式查看SQL
    result := db.Debug().Table("sessionusernames").Where("username = ?", "Erwan").First(&session)
    
    if result.Error != nil {
        if errors.Is(result.Error, gorm.ErrRecordNotFound) {
            fmt.Println("记录不存在")
        } else {
            fmt.Printf("查询错误: %v\n", result.Error)
        }
        return
    }
    
    if session.ID == 0 {
        fmt.Println("查询结果为空")
    } else {
        fmt.Printf("找到记录: ID=%d, Username=%s\n", session.ID, session.Username)
    }
}

5. 检查数据库连接和表结构

确保:

  • 数据库连接字符串正确
  • 表名和字段名大小写匹配(特别是MySQL在Linux下区分大小写)
  • 表结构中的字段与结构体字段对应

主要问题在于你的空值检查方式不正确,应该检查result.Errorsession.ID是否为0,而不是比较整个结构体。

回到顶部