La pila LAMP ha sido muy popular en internet los últimos años. La M en LAMP significa MySQL. MySQL es famoso porque es de código abierto y fácil de usar. También porque viene como base de datos por defecto en el backend de muchos sitios web.
Existen varios manejadores que soportan MySQL en Go. Algunos de ellos implementan la interfaz database/sql
, y otros usan sus propias interfaces estándares.
- https://github.com/go-sql-driver/mysql soporta
database/sql
, está escrita en Go puro. - https://github.com/ziutek/mymysql soporta
database/sql
e interfaces definidas por el usuario, está escrita en Go puro.
Usaré el primer manejador en los siguientes ejemplos (uso este en mis proyectos personales también) y también lo recomiendo por las siguientes razones:
- Es un manejador de bases de datos nuevo y suporta muchas características
- Soporta completamente la interfaz
database/sql
- Soporta el keep-alive, conexiones largas con seguridad entre hilos
En las siguientes secciones usaré las misma estructura de tablas para diferentes bases de datos, luego crear la base de datos de la siguiente manera:
CREATE TABLE `userinfo` (
`uid` INT(10) NOT NULL AUTO_INCREMENT,
`username` VARCHAR(64) NULL DEFAULT NULL,
`department` VARCHAR(64) NULL DEFAULT NULL,
`created` DATE NULL DEFAULT NULL,
PRIMARY KEY (`uid`)
);
El siguiente ejemplo muestra como operar en bases de datos con los estándares de database/sql
.
package main
import (
_ "github.com/go-sql-driver/mysql"
"database/sql"
"fmt"
)
func main() {
db, err := sql.Open("mysql", "astaxie:astaxie@/test?charset=utf8")
checkErr(err)
// insertar
stmt, err := db.Prepare("INSERT userinfo SET username=?,department=?,created=?")
checkErr(err)
res, err := stmt.Exec("astaxie", "研发部门", "2012-12-09")
checkErr(err)
id, err := res.LastInsertId()
checkErr(err)
fmt.Println(id)
// actualizar
stmt, err = db.Prepare("update userinfo set username=? where uid=?")
checkErr(err)
res, err = stmt.Exec("astaxieupdate", id)
checkErr(err)
affect, err := res.RowsAffected()
checkErr(err)
fmt.Println(affect)
// consultar
rows, err := db.Query("SELECT * FROM userinfo")
checkErr(err)
for rows.Next() {
var uid int
var username string
var department string
var created string
err = rows.Scan(&uid, &username, &department, &created)
checkErr(err)
fmt.Println(uid)
fmt.Println(username)
fmt.Println(department)
fmt.Println(created)
}
// eliminar
stmt, err = db.Prepare("delete from userinfo where uid=?")
checkErr(err)
res, err = stmt.Exec(id)
checkErr(err)
affect, err = res.RowsAffected()
checkErr(err)
fmt.Println(affect)
db.Close()
}
func checkErr(err error) {
if err != nil {
panic(err)
}
}
Permítanme explicar algunas de las funciones importantes aquí:
sql.Open()
abre un manejador de bases de datos registrado. Go-MySQL-Driver registra el manejador de MySQL aquí. El segundo argumento es el DSN (Data Source Name) que define la información para realizar la conexión con la base de datos. Soporta los siguientes formatos:
user@unix(/path/to/socket)/dbname?charset=utf8
user:password@tcp(localhost:5555)/dbname?charset=utf8
user:password@/dbname
user:password@tcp([de:ad:be:ef::ca:fe]:80)/dbname
db.Prepare()
retorna la operación que va a ser ejecutada. También reetorna el estado de ejecución después de ejecutar el SQL.db.Query()
ejecuta el SQL y retorna el resultado en Rowsstmt.Exec()
ejecuta el SQL que ha sido preparado y almacenado en un Stmt
Note que usamos el formato =?
para pasar argumentos. Esto es necesario para prevenir ataques de inyección SQL.
- Índice
- Sección previa: Interfaz database/sql
- Siguiente sección: SQLite