php小编鱼仔在这篇文章中将向大家介绍如何实现database/sql.Scanner接口。在Go语言中,database/sql包是用于操作关系型数据库的核心包。Scanner接口用于将数据库查询结果中的值扫描到Go语言的变量中。通过实现Scanner接口,我们可以自定义将数据库查询结果中的值转换为我们想要的类型。本文将详细讲解如何实现Scanner接口,帮助读者更好地理解和应用Go语言中的数据库操作。
如何实现database/sql.Scanner
接口?
在此查询中,SELECT 子句中有 3 个字段:
id
smallint 无符号is_suspended
tinyint 无符号name
varchar在database/sql
中,3列的数据类型是:
int64
int64
[]uint8
这适用于 []接口{}
,但希望将每个列类型直接实现到 []接口{}
,但希望将每个列类型直接实现到 database/sql.Scanner
接口
cols := make([]interface{}, 3) ptr := make([]interface{}, 3) for i, _ := range cols { ptr[i] = &cols[i] } if err := rows.Scan(ptr...); err != nil { fmt.Println("err:", err) } // pair column data with column name res := map[string]any for i, name := range res_cols { res[name] = *ptr[i].(*any) fmt.Printf("Type: %T %s\n", res[name], name) }
我尝试做的事情,但无法真正使其发挥作用
类型
type Type_int int func (t *Type_int) Scan(value interface{}) error { switch value := value.(type) { case int64: *t = Type_int(value) default: return fmt.Errorf("Invalid database type: %T %v", value, value) } return nil } type Type_string string func (t *Type_string) Scan(value interface{}) error { switch value := value.(type) { case []uint8: *t = Type_string(value) default: return fmt.Errorf("Invalid database type: %T %v", value, value) } return nil }
代码
ptr := make([]interface{}, 3) cols := []interface{}{ Type_int, Type_int, Type_string, } for i, _ := range cols { ptr[i] = &cols[i] } if err := rows.Scan(ptr...); err != nil { fmt.Println("err:", err) } // pair column data with column name res := map[string]any for i, name := range res_cols { res[name] = *ptr[i].(*any) fmt.Printf("Type: %T %s\n", res[name], name) }
使用指向给定类型值的指针初始化 ptr
。
var c1 Type_int var c2 Type_int var c3 Type_string ptr := []any{&c1, &c2, &c3} if err := rows.Scan(ptr...); err != nil { fmt.Println("err:", err) }
ptr
切片在上面的代码片段中没有提供任何值。代码可以简化为:
var c1 Type_int var c2 Type_int var c3 Type_string if err := rows.Scan(&c1, &c2, &c3); err != nil { fmt.Println("err:", err) }
以上是实现database/sql.Scanner接口的详细内容。更多信息请关注PHP中文网其他相关文章!