Maison > développement back-end > Golang > Comment utiliser Reflection pour appeler la fonction variadique Database/SQL Rows.Scan() ?

Comment utiliser Reflection pour appeler la fonction variadique Database/SQL Rows.Scan() ?

Mary-Kate Olsen
Libérer: 2024-12-05 09:56:11
original
756 Les gens l'ont consulté

How to Use Reflection to Call the Database/SQL Rows.Scan() Variadic Function?

Appel de la fonction variadique Scan() avec réflexion

La fonction Rows.Scan() fournit un moyen pratique de récupérer des données à partir d'une base de données requête. Cependant, il utilise un nombre variable de pointeurs comme arguments, ce qui peut être difficile à intégrer par réflexion. Considérez le scénario suivant :

Vous souhaitez remplir dynamiquement une tranche avec les valeurs obtenues à partir d'une requête et utiliser Rows.Scan() pour extraire les données. Dans ce cas, vous devrez déterminer le nombre de colonnes et créer une tranche pour stocker les valeurs.

Un piège courant :
Une tentative d'utiliser la réflexion pour appeler le La fonction Scan() peut conduire à des résultats inattendus. En effet, Rows.Scan() attend des pointeurs vers les valeurs, et le simple passage d'une tranche de valeurs d'interface{} entraînerait des références nulles.

La solution :

Pour appeler avec succès Scan() avec réflexion, une approche à double tranche est utilisée. La première tranche, valeurs, contient les données réelles, tandis que la deuxième tranche, valeursPtrs, contient des pointeurs vers chaque élément dans valeurs.

Pour chaque colonne du résultat de la requête, un pointeur dans valeursPtrs est mappé vers l'élément correspondant. en valeurs. Par la suite, Rows.Scan() peut être invoquée avec valuesPtrs comme argument, remplissant efficacement les valeurs.

Exemple de travail :

package main

import (
    "fmt"
    _ "github.com/lib/pq"
    "database/sql"
)

func main() {
    db, _ := sql.Open(
        "postgres",
        "user=postgres dbname=go_testing password=pass sslmode=disable")

    rows, _ := db.Query("SELECT * FROM _user;")

    columns, _ := rows.Columns()
    count := len(columns)
    values := make([]interface{}, count)
    valuesPtrs := make([]interface{}, count)

    for rows.Next() {
        for i := range columns {
            valuesPtrs[i] = &values[i]
        }

        rows.Scan(valuesPtrs...)

        for i, col := range columns {
            val := values[i]

            b, ok := val.([]byte)
            var v interface{}
            if (ok) {
                v = string(b)
            } else {
                v = val
            }

            fmt.Println(col, v)
        }
    }
}
Copier après la connexion

Dans cet exemple, les lignes. Scan() est invoqué avec la tranche de pointeur valeursPtrs, remplissant la tranche de valeurs avec les données récupérées. La boucle imprime ensuite chaque nom de colonne et sa valeur correspondante.

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!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal