Skip to content

MySQL

MySQL es actualmente la base de datos relacional de código abierto más popular. No se profundizará demasiado en conocimientos específicos de SQL aquí; si no sabes, por favor aprende primero por tu cuenta. Este artículo solo explica brevemente cómo usar Go para realizar operaciones SQL. En proyectos, generalmente no se usa directamente el controlador para operaciones de base de datos, sino que se utiliza un marco ORM. Aquí se usa la biblioteca sqlx, que es una mejora de la biblioteca estándar sql, no tan rica en funciones ORM pero más concisa. Si quieres usar un ORM, puedes explorar bibliotecas como Gorm, Xorm o Ent.

Dependencias

Descarga la biblioteca sqlx:

bash
$ go get github.com/jmoiron/sqlx

sqlx o la biblioteca estándar database/sql soportan no solo MySQL, sino cualquier base de datos que implemente la interfaz driver.Driver, por ejemplo:

  • PostgreSQL
  • Oracle
  • MariaDB
  • SQLite
  • Y otras bases de datos relacionales

Para usar una base de datos específica, necesitas implementar el controlador correspondiente. El controlador puede ser escrito por ti mismo o ser una biblioteca de terceros. Antes de usarlo, debes registrar el controlador con sql.Register para poder usarlo. Sin embargo, generalmente las bibliotecas de controladores descargadas registran automáticamente el controlador, sin necesidad de registro manual.

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

Debido a que MySQL es popular y simple, este artículo usa MySQL para explicar. Otras bases de datos relacionales se operan de manera similar. Descarga la biblioteca del controlador MySQL:

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

Conectar a la base de datos

Usando la función sqlx.Open, puedes abrir una conexión a la base de datos. Acepta dos parámetros: el primero es el nombre del controlador y el segundo es la fuente de datos (generalmente abreviada como DSN).

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

El nombre del controlador debe coincidir con el usado al registrar el controlador. El DSN es la dirección de conexión de la base de datos, que puede variar según la base de datos. Para MySQL, es así:

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

Preparar datos

sql
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Estructura de la tabla 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;

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

SET FOREIGN_KEY_CHECKS = 1;

Consulta

Consulta y mapea los resultados a una estructura:

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
   // Para uno es Get, para varios es 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)
}

Insertar

Insertar datos:

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

Actualizar

Actualizar datos:

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

Eliminar

Eliminar datos:

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

Transacciones

go
func (db *DB) Begin() (*Tx, error) // Iniciar una transacción
func (tx *Tx) Commit() error // Confirmar una transacción
func (tx *Tx) Rollback() error // Revertir una transacción

Al iniciar una transacción, por seguridad siempre se agrega defer tx.Rollback(). Si hay un error durante el proceso, se revertirá. Si la transacción se confirma exitosamente, el rollback naturalmente no tiene efecto.

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 editado por www.golangdev.cn