php editor Yuzai will introduce to you how to implement the database/sql.Scanner interface in this article. In the Go language, the database/sql package is the core package used to operate relational databases. The Scanner interface is used to scan the values in the database query results into Go language variables. By implementing the Scanner interface, we can customize the conversion of the values in the database query results into the type we want. This article will explain in detail how to implement the Scanner interface to help readers better understand and apply database operations in the Go language.
How to implement the database/sql.Scanner
interface?
In this query, there are 3 fields in the SELECT clause:
id
smallint unsignedis_suspended
tinyint unsignedname
varcharIn database/sql
, the data type of the 3 columns is:
int64
int64
[]uint8
This works for []interface{}
, but would like to implement each column type directly into the database/sql.Scanner
interface
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) }
Things I tried to do but couldn't really make it work
type
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 }
Code
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) }
Initialize ptr
with a pointer to a value of the given type.
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
The slice does not provide any value in the above snippet. The code can be simplified to:
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) }
The above is the detailed content of Implement database/sql.Scanner interface. For more information, please follow other related articles on the PHP Chinese website!