Utilisez le package database/sql de Go conjointement avec les instructions SQL LindormTable pour vous connecter à LindormTable et effectuer des opérations CRUD. Ce guide détaille les étapes suivantes :
Ajouter la dépendance du pilote MySQL pour Go
Configurer les paramètres de connexion et le pool de connexions
Créer une table, écrire, interroger et supprimer des données
Exécuter l'exemple d'application complet et vérifier les résultats
Prérequis
Avant de commencer, assurez-vous de disposer des éléments suivants :
Go 1.17 ou version ultérieure. Consultez la documentation Go pour les instructions d'installation.
La compatibilité MySQL activée sur votre instance Lindorm. Consultez la section Activer la fonctionnalité de compatibilité MySQL.
L'adresse IP de votre client ajoutée à la liste d'autorisation de l'instance Lindorm. Consultez la section Configurer les listes d'autorisation.
Notes sur la connexion et la fiabilité
Les nœuds frontaux SQL de LindormTable utilisent Server Load Balancer (SLB) pour répartir les requêtes des clients entre les nœuds frontaux. Pour maintenir une répartition équilibrée des connexions, évitez les temps de maintien de connexion trop longs. Configurez
SetConnMaxLifetimeafin d'actualiser périodiquement les connexions.Dans des environnements réseau complexes (latence élevée, perte de paquets ou gigue réseau), les connexions peuvent être interrompues. Configurez un pool de connexions approprié et implémentez une logique de nouvelle tentative dans le code de votre application.
Lorsque le serveur redémarre pendant les mises à niveau, les connexions peuvent être temporairement perdues. Même avec un pool de connexions, votre application peut rencontrer des exceptions. Interceptez ces erreurs et effectuez une nouvelle tentative.
-
Ajustez les paramètres du pool de connexions en fonction de votre trafic. Un nombre insuffisant de connexions entraîne la mise en file d'attente des requêtes et augmente le temps de réponse (RT). Affichez l'état du pool pour diagnostiquer les problèmes de connexion :
fmt.Printf("%+v\n", db.Stats())
Se connecter à LindormTable
Étape 1 : Ajouter la dépendance du pilote
Dans le fichier go.mod de votre projet, ajoutez le pilote MySQL pour Go :
require github.com/go-sql-driver/mysql v1.7.1
Étape 2 : Configurer les paramètres de connexion
Définissez vos constantes de connexion :
const (
user = "<your-username>"
password = "<your-password>"
host = "<LindormTable-endpoint-for-MySQL>"
port = 33060
database = "default"
connectTimeout = "10s"
)
Référence des paramètres
| Paramètre | Description |
|---|---|
user |
Nom d'utilisateur pour l'accès à LindormTable. Pour réinitialiser le mot de passe, consultez la rubrique Gérer les utilisateurs. |
password |
Mot de passe pour l'accès à LindormTable. |
host |
LindormTable Endpoint For MySQL. Consultez la rubrique Afficher les endpoints. Pour les applications déployées sur ECS, utilisez l'endpoint VPC pour une latence plus faible et une sécurité accrue. Pour un accès Internet, activez l'endpoint public dans la console : Database Connections > Wide Table Engine > Enable Public Endpoint. |
port |
Valeur fixe : 33060. |
database |
Nom de la base de données. La valeur par défaut est default. |
connectTimeout |
Délai d'expiration de la connexion. Unité : secondes (s). |
Étape 3 : Ouvrir une connexion et configurer le pool
Construisez l'URL de connexion et configurez les paramètres du pool avant d'exécuter toute requête :
url := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?timeout=%s",
user, password, host, port, database, connectTimeout)
db, err := sql.Open("mysql", url)
if err != nil {
panic(err.Error())
}
defer db.Close()
// Maximum number of open connections. Default: 0 (unlimited).
// Set this to avoid waiting when connections are exhausted.
db.SetMaxOpenConns(20)
// Maximum number of idle connections. Default: 2.
// Set equal to SetMaxOpenConns to avoid unnecessary connection churn.
db.SetMaxIdleConns(20)
// Maximum idle time before a connection is closed. Default: 0 (no limit).
// 8 minutes is a safe default to reclaim stale idle connections.
db.SetConnMaxIdleTime(8 * time.Minute)
// Maximum connection lifetime. Rotate connections to avoid imbalance
// caused by long-lived persistent connections. 30 minutes recommended.
db.SetConnMaxLifetime(30 * time.Minute)
Exemples de code
Tous les exemples utilisent db.Exec, db.Query et db.Prepare du package standard database/sql de Go.
Lister les bases de données
rows, err := db.Query("show databases")
if err != nil {
panic(err.Error())
}
defer rows.Close()
for rows.Next() {
var dbName string
if err := rows.Scan(&dbName); err != nil {
panic(err.Error())
}
fmt.Println(dbName)
}
Créer une table
_, err := db.Exec("create table if not exists user_test(id int, name varchar,age int, primary key(id))")
if err != nil {
fmt.Println("create table error", err)
return
}
Écrire des données
Écriture directe
_, err = db.Exec("upsert into user_test(id,name,age) values(1,'zhangsan',17)")
if err != nil {
fmt.Println("insert data error", err)
return
}
Écriture paramétrée (recommandée pour les écritures répétées — réutilisez Stmt pour les scénarios à haut débit)
stmt, err := db.Prepare("upsert into user_test(id,name,age) values(?,?,?)")
if err != nil {
fmt.Println("prepare error", err)
return
}
defer stmt.Close()
_, err = stmt.Exec(2, "lisi", 18)
if err != nil {
fmt.Println("upsert error", err)
return
}
Interroger des données
Requête directe
rows, err := db.Query("select * from user_test")
if err != nil {
fmt.Println("query data error", err)
return
}
defer rows.Close()
var id int
var name string
var age int
for rows.Next() {
if err = rows.Scan(&id, &name, &age); err != nil {
fmt.Println("scan data error", err)
return
}
fmt.Println("id:", id, "name:", name, "age:", age)
}
Requête paramétrée
stmt, err := db.Prepare("select * from user_test where id=?")
if err != nil {
fmt.Println("prepare error", err)
return
}
defer stmt.Close()
rows, err := stmt.Query(1)
if err != nil {
fmt.Println("query data error", err)
return
}
defer rows.Close()
var id int
var name string
var age int
for rows.Next() {
if err = rows.Scan(&id, &name, &age); err != nil {
fmt.Println("scan data error", err)
return
}
fmt.Println("id:", id, "name:", name, "age:", age)
}
Supprimer des données
_, err = db.Exec("delete from user_test where id=1")
if err != nil {
fmt.Println("delete data error", err)
return
}
Exemple de code complet
Voici un exemple exécutable de bout en bout qui se connecte à LindormTable, crée une table, écrit des lignes, les interroge et en supprime une.
En production, chargez les identifiants à partir de variables d'environnement au lieu de les coder en dur dans le code source.
package main
import (
"database/sql"
"fmt"
"time"
_ "github.com/go-sql-driver/mysql"
)
const (
// Set user to the username used to access LindormTable
user = "user"
// Set password to the password used to access LindormTable
password = "test"
// Set host to the LindormTable endpoint for MySQL
host = "ld-uf6k8yqb741t3****-proxy-sql-lindorm-public.lindorm.rds.aliyuncs.com"
// Port is fixed to 33060
port = 33060
// Set database to the name of the database to connect to
database = "default"
// Connection timeout
connectTimeout = "20s"
)
func main() {
// Build the connection URL and open the connection
url := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?timeout=%s",
user, password, host, port, database, connectTimeout)
db, err := sql.Open("mysql", url)
if err != nil {
panic(err.Error())
}
defer db.Close()
// Configure connection pool
db.SetMaxOpenConns(20)
db.SetMaxIdleConns(20)
db.SetConnMaxIdleTime(8 * time.Minute)
db.SetConnMaxLifetime(30 * time.Minute)
// Print pool status every 10 seconds for diagnostics
go func() {
for {
fmt.Printf("%+v\n", db.Stats())
time.Sleep(10 * time.Second)
}
}()
// List databases
{
rows, err := db.Query("show databases")
if err != nil {
panic(err.Error())
}
defer rows.Close()
for rows.Next() {
var dbName string
if err := rows.Scan(&dbName); err != nil {
panic(err.Error())
}
fmt.Println(dbName)
}
}
// Create a table
{
_, err := db.Exec("create table if not exists user_test(id int, name varchar,age int, primary key(id))")
if err != nil {
fmt.Println("create table error ", err)
return
}
}
// Write data — method 1: direct write
{
_, err = db.Exec("upsert into user_test(id,name,age) values(1,'zhangsan',17)")
if err != nil {
fmt.Println("insert data error", err)
return
}
}
// Write data — method 2: parameterized write
{
stmt, err := db.Prepare("upsert into user_test(id,name,age) values(?,?,?)")
if err != nil {
fmt.Println("prepare error", err)
return
}
defer stmt.Close()
_, err = stmt.Exec(2, "lisi", 18)
if err != nil {
fmt.Println("upsert error", err)
return
}
}
// Query data — method 1: direct query
{
rows, err := db.Query("select * from user_test")
if err != nil {
fmt.Println("query data error", err)
return
}
defer rows.Close()
var id int
var name string
var age int
for rows.Next() {
if err = rows.Scan(&id, &name, &age); err != nil {
fmt.Println("scan data error", err)
return
}
fmt.Println("id:", id, "name:", name, "age:", age)
}
}
// Query data — method 2: parameterized query
{
stmt, err := db.Prepare("select * from user_test where id=?")
if err != nil {
fmt.Println("prepare error", err)
return
}
defer stmt.Close()
rows, err := stmt.Query(1)
if err != nil {
fmt.Println("query data error", err)
return
}
defer rows.Close()
var id int
var name string
var age int
for rows.Next() {
if err = rows.Scan(&id, &name, &age); err != nil {
fmt.Println("scan data error", err)
return
}
fmt.Println("id:", id, "name:", name, "age:", age)
}
}
// Delete data
{
_, err = db.Exec("delete from user_test where id=1")
if err != nil {
fmt.Println("delete data error", err)
return
}
}
}
Appelez toujoursrows.Close()après avoir itéré sur les résultats. Pour les scénarios à haut débit, réutilisez les objetsStmt. Lors de l'utilisation d'API sensibles au contexte telles queQueryContextetExecContext, évitez les délais d'expiration très courts ; les pauses du garbage collection (GC) côté client peuvent déclencher des délais d'expiration du contexte et provoquer des réinitialisations de connexion.
Vérifier les résultats
Lorsque l'instance ne contient que la base de données default, la sortie est la suivante :
default
information_schema
id: 1 name: zhangsan age: 17
id: 2 name: lisi age: 18
id: 1 name: zhangsan age: 17
Cette sortie confirme que :
defaultetinformation_schema— deux bases de données existent sur l'instance.id: 1 name: zhangsan age: 17etid: 2 name: lisi age: 18— les deux lignes ont été écrites avec succès.id: 1 name: zhangsan age: 17— la requête paramétrée (where id=?) a renvoyé la ligne avecid=1.
Étapes suivantes
Gérer les utilisateurs — modifier les mots de passe et gérer l'accès
Afficher les endpoints — trouver les endpoints VPC et publics
Configurer les listes d'autorisation — gérer les listes d'autorisation d'adresses IP