
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 thedatabase/sql.Scannerinterface?
In this query, there are 3 fields in the SELECT clause:
idsmallint unsignedis_suspendedtinyint unsignednamevarcharIndatabase/sql, the data type of the 3 columns is:
int64int64[]uint8This works for[]interface{}, but would like to implement each column type directly into thedatabase/sql.Scannerinterface
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) }
Initializeptrwith 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) }
ptrThe 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!
Usage of Type keyword in Go
How to implement linked list in go
What are the Go language programming software?
How to learn go language from 0 basics
What are the methods to implement operator overloading in Go language?
What are the operators in Go language?
What should I do if I can only send one private message on TikTok?
What are the commonly used third-party libraries in PHP?