Maison  >  Article  >  développement back-end  >  Implémenter l'interface base de données/sql.Scanner

Implémenter l'interface base de données/sql.Scanner

王林
王林avant
2024-02-10 13:30:08578parcourir

Implémenter linterface base de données/sql.Scanner

l'éditeur php Yuzai vous présentera comment implémenter l'interface database/sql.Scanner dans cet article. Dans le langage Go, le package base de données/sql est le package de base utilisé pour faire fonctionner les bases de données relationnelles. L'interface Scanner est utilisée pour analyser les valeurs des résultats de la requête de base de données dans les variables du langage Go. En implémentant l'interface Scanner, nous pouvons personnaliser la conversion des valeurs des résultats de la requête de base de données dans le type souhaité. Cet article expliquera en détail comment implémenter l'interface Scanner pour aider les lecteurs à mieux comprendre et appliquer les opérations de base de données dans le langage Go.

Contenu de la question

Comment implémenter l'database/sql.Scannerinterface ?

Dans cette requête, il y a 3 champs dans la clause SELECT :

  • idsmallint non signé
  • is_suspended tinyint non signé
  • namevarchar

Dans database/sql, le type de données des 3 colonnes est :

  • int64
  • int64
  • []uint8

Cela fonctionne pour []interface{}, mais j'aimerais implémenter chaque type de colonne directement dans l'[]接口{},但希望将每个列类型直接实现到 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)
}

Choses que j'ai essayé de faire mais je n'ai pas vraiment réussi à le faire fonctionner

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)
}

Solution de contournement

Initialisez ptr avec un pointeur vers une valeur du type donné.

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 Slice ne fournit aucune valeur dans l'extrait ci-dessus. Le code peut être simplifié comme suit :

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)
}

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer