Heim  >  Artikel  >  Backend-Entwicklung  >  Implementieren Sie die Datenbank/sql.Scanner-Schnittstelle

Implementieren Sie die Datenbank/sql.Scanner-Schnittstelle

王林
王林nach vorne
2024-02-10 13:30:08575Durchsuche

Implementieren Sie die Datenbank/sql.Scanner-Schnittstelle

php-Editor Yuzai wird Ihnen in diesem Artikel vorstellen, wie Sie die Datenbank/sql.Scanner-Schnittstelle implementieren. In der Go-Sprache ist das Datenbank-/SQL-Paket das Kernpaket für den Betrieb relationaler Datenbanken. Die Scanner-Schnittstelle wird verwendet, um die Werte in den Datenbankabfrageergebnissen in Go-Sprachvariablen zu scannen. Durch die Implementierung der Scanner-Schnittstelle können wir die Konvertierung der Werte in den Datenbankabfrageergebnissen in den gewünschten Typ anpassen. In diesem Artikel wird ausführlich erläutert, wie die Scanner-Schnittstelle implementiert wird, um den Lesern zu helfen, Datenbankoperationen in der Go-Sprache besser zu verstehen und anzuwenden.

Frageninhalt

Wie implementiert man die database/sql.ScannerSchnittstelle?

In dieser Abfrage gibt es 3 Felder in der SELECT-Klausel:

  • idsmallint unsigned
  • is_suspended tinyint unsigned
  • namevarchar

In database/sql ist der Datentyp von 3 Spalten:

  • int64
  • int64
  • []uint8

Dies funktioniert für []interface{}, möchte aber jeden Spaltentyp direkt in die []接口{},但希望将每个列类型直接实现到 database/sql.Scanner Schnittstelle

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

Dinge, die ich versucht habe, es aber nicht wirklich zum Laufen bringen konnten

Typ

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

Workaround

Initialisieren ptr mit einem Zeiger auf einen Wert des angegebenen Typs.

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 bietet im obigen Snippet keinen Wert. Der Code kann wie folgt vereinfacht werden:

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

Das obige ist der detaillierte Inhalt vonImplementieren Sie die Datenbank/sql.Scanner-Schnittstelle. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:stackoverflow.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen