Skip to content

MySQL

MySQL è attualmente il database relazionale open source più popolare. Le conoscenze SQL specifiche non verranno trattate in dettaglio qui. Se non le conosci, ti preghiamo di studiarle autonomamente. Questo articolo spiega semplicemente come utilizzare Go per eseguire operazioni SQL. In un progetto, generalmente non si utilizza direttamente il driver per operare il database, ma si utilizza un framework ORM. Qui utilizziamo la libreria sqlx, che è un potenziamento della libreria standard sql, non è ricca di funzionalità ORM ma vince in semplicità. Se desideri utilizzare un ORM, puoi consultare librerie come Gorm, Xorm, Ent.

Dipendenze

Scarica la libreria sqlx

bash
$ go get github.com/jmoiron/sqlx

sqlx o la libreria standard database/sql supportano non solo MySQL, ma qualsiasi tipo che implementi l'interfaccia driver.Driver è supportato, ad esempio:

  • PostgreSQL
  • Oracle
  • MariaDB
  • SQLite
  • Altri database relazionali

Per utilizzare un database corrispondente, è necessario implementare il driver del database. Il driver può essere scritto da te o provenire da una libreria di terze parti. Prima dell'uso, è necessario registrare il driver utilizzando sql.Register, quindi è possibile utilizzarlo. Tuttavia, generalmente le librerie driver scaricate registreranno automaticamente il driver, non è necessario registrarlo manualmente.

go
func Register(name string, driver driver.Driver)

Poiché MySQL è piuttosto popolare e anche il più semplice, questo articolo utilizza MySQL per la spiegazione. Le operazioni con altri database relazionali sono più o meno simili. Scarica la libreria driver MySQL

bash
$ go get github.com/go-sql-driver/mysql

Connessione al database

Tramite la funzione sqlx.Open, è possibile aprire una connessione al database. Accetta due parametri: il primo è il nome del driver, il secondo è la fonte dati (generalmente abbreviata in DSN).

go
func Open(driverName, dataSourceName string) (*DB, error)

Il nome del driver è il nome utilizzato quando si registra il driver, deve essere coerente. Il DSN è l'indirizzo di connessione del database, ogni database può essere diverso. Per MySQL è come segue

go
db,err := sqlx.Open("mysql","root:123456@tcp(127.0.0.1:3306)/test")

Preparazione dei dati

sql
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Struttura tabella user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user`  (
  `id` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL,
  `age` tinyint(0) NULL DEFAULT NULL,
  `address` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin ROW_FORMAT = Dynamic;

-- ----------------------------
-- Record di user
-- ----------------------------
INSERT INTO `user` VALUES ('12132', '张三', 35, '北京市');
INSERT INTO `user` VALUES ('16162', '王五', 22, '上海市');

SET FOREIGN_KEY_CHECKS = 1;

Interrogazione

Interrogare e mappare i risultati in una struttura

go
var db *sqlx.DB

type Person struct {
   UserId   string `db:"id"`
   Username string `db:"name"`
   Age      int    `db:"age"`
   Address  string `db:"address"`
}

func init() {
    conn, err := sqlx.Open("mysql", "root:wyh246859@tcp(127.0.0.1:3306)/test")
   if err != nil {
      fmt.Println("Open mysql failed", err)
      return
   }

   db = conn
}

func main() {
   query()
   defer db.Close()
}

func query() {
   var person Person
   // Per uno è Get, per multipli è Select
   err := db.Get(&person, "select * from user where id = ?", "12132")
   if err != nil {
      fmt.Println("query failed:", err)
      return
   }
   fmt.Printf("query succ:%+v", person)
}

func list() {
  var perons []Person
  err := db.Select(&perons, "select * from user")
  if err != nil {
    fmt.Println("list err", err)
    return
  }
  fmt.Printf("list succ,%+v", perons)
}

Inserimento

Inserire dati

go
func insert() {
   result, err := db.Exec("insert into user value (?,?,?,?)", "120230", "李四", 12, "广州市")
   if err != nil {
      fmt.Println("insert err:", err)
      return
   }
   id, err := result.LastInsertId()
   if err != nil {
      fmt.Println("insert err:", err)
      return
   }
   fmt.Println("insert succ:", id)
}

Aggiornamento

Aggiornare dati

go
func update() {
   res, err := db.Exec("update user set name = ? where id = ?", "赵六", "120230")
   if err != nil {
      fmt.Println("update err:", err)
      return
   }
   eff, err := res.RowsAffected()
   if err != nil || eff == 0 {
      fmt.Println("update err:", err)
      return
   }
   fmt.Println("Update succ")
}

Eliminazione

Eliminare dati

go
func delete() {
   res, err := db.Exec("delete from user where id = ?", "120230")
   if err != nil {
      fmt.Println("delete err:", err)
      return
   }
   eff, err := res.RowsAffected()
   if err != nil || eff == 0 {
      fmt.Println("delete err:", err)
      return
   }
   fmt.Println("delete succ")
}

Transazioni

go
func (db *DB) Begin() (*Tx, error) // Avvia una transazione
func (tx *Tx) Commit() error // Conferma una transazione
func (tx *Tx) Rollback() error // Annulla una transazione

Quando si avvia una transazione, per sicurezza si aggiunge sempre defer tx.Rollback(). Se qualcosa va sbagliato durante il processo, verrà eseguito il rollback. Se la transazione viene confermata con successo, naturalmente questo rollback non sarà valido.

go
func main() {

  transation, err := db.Begin()
  if err != nil {
    fmt.Println("transation err")
  }
    defer transation.Rollback()

  insert()
  query()
  update()
  query()
  delete()
   transation.Commit()
}

Golang by www.golangdev.cn edit