go语言数据库操作:巧妙地将db.QueryRow.Scan结果映射到map
在Go语言数据库操作中,将查询结果映射到自定义结构体是常见做法。然而,有时需要将结果映射到map中。本文将详细讲解如何将db.QueryRow.Scan的结果扫描到map[String]interface{}中,并解决常见错误。
直接使用map[string]Interface{}作为Scan的参数是错误的,因为Scan函数需要的是指针,以便写入数据。 以下代码片段展示了常见的错误:
res := map[string]interface{}{"id": nil, "name": nil, "password": nil, "add_time": nil} // ... Scan(res["id"], res["name"], ...) // 错误!
res[“id”]等返回的是interface{}类型的值,而不是指针。 Scan函数无法将数据写入到这些值中。
立即学习“go语言免费学习笔记(深入)”;
正确的做法是为每个map值分配内存空间,并使用指针:
res := map[string]interface{}{"id": new(int), "name": new(string), "password": new(string), "add_time": new(int64)}
这里使用new()函数为int、string和int64类型分别分配内存,并得到它们的指针。 Scan函数可以将数据写入这些指针指向的内存地址。
改进后的selectOne函数如下:
func selectOne(id int) { res := map[string]interface{}{"id": new(int), "name": new(string), "password": new(string), "add_time": new(int64)} fmt.Println("Initial map:", res) // 添加打印语句,方便调试 sql := "select id, name, password, add_time from test where id = ?" err := db.QueryRow(sql, id).Scan(res["id"], res["name"], res["password"], res["add_time"]) if err != nil { fmt.Println("获取数据失败:", err.Error()) } else { fmt.Println("Result map:", res) // 添加打印语句,方便调试 // 访问map中的数据 idVal := *res["id"].(*int) nameVal := *res["name"].(*string) // ... } }
请注意,访问map中的数据需要进行类型断言,例如*res[“id”].(*int)。 这确保了正确地将interface{}转换为int类型。 我们还添加了打印语句,方便调试和理解数据流向。 sql语句也进行了调整,明确指定了要查询的列名,以避免潜在的列名不匹配问题。 记住,map的键名必须与数据库列名一致。
通过这种方法,可以有效地将db.QueryRow.Scan的结果映射到map中,并避免常见的指针错误。 记住始终为map中的值分配内存并使用指针。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END