在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.Error或session.ID是否为0,而不是比较整个结构体。