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:
$ go get github.com/jmoiron/sqlxsqlx 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.
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:
$ go get github.com/go-sql-driver/mysqlConectar 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).
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í:
db,err := sqlx.Open("mysql","root:123456@tcp(127.0.0.1:3306)/test")Preparar datos
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:
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:
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:
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:
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
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ónAl 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.
func main() {
transation, err := db.Begin()
if err != nil {
fmt.Println("transation err")
}
defer transation.Rollback()
insert()
query()
update()
query()
delete()
transation.Commit()
}