Skip to content

MySQL

Mysql là cơ sở dữ liệu quan hệ mã nguồn mở phổ biến nhất hiện nay. Các kiến thức sql cụ thể sẽ không được trình bày quá nhiều ở đây, nếu bạn chưa biết vui lòng tự học trước. Bài viết này chỉ đơn giản giải thích cách sử dụng Go để thao tác sql. Trong dự án thực tế, thông thường không sử dụng trực tiếp trình điều khiển để thao tác cơ sở dữ liệu mà sử dụng các framework ORM. Ở đây sử dụng thư viện sqlx, là một thư viện mở rộng của thư viện sql tiêu chuẩn, không có nhiều chức năng như ORM nhưng bù lại rất đơn giản và gọn nhẹ. Nếu bạn muốn sử dụng ORM, có thể tìm hiểu các thư viện như Gorm, Xorm, Ent.

Phụ thuộc

Tải xuống thư viện sqlx

bash
$ go get github.com/jmoiron/sqlx

sqlx hoặc thư viện database/sql tiêu chuẩn hỗ trợ không chỉ MySQL, bất kỳ loại nào thực hiện giao diện driver.Driver đều được hỗ trợ, ví dụ:

  • PostgreSQL
  • Oracle
  • MariaDB
  • SQLite
  • Và các cơ sở dữ liệu quan hệ khác

Để sử dụng cơ sở dữ liệu tương ứng, cần thực hiện trình điều khiển cơ sở dữ liệu. Trình điều khiển có thể do bạn tự viết hoặc từ thư viện bên thứ ba. Trước khi sử dụng, bạn cần đăng ký trình điều khiển bằng sql.Register, sau đó mới có thể sử dụng. Tuy nhiên, các thư viện trình điều khiển tải xuống thường tự động đăng ký trình điều khiển, không cần bạn phải đăng ký thủ công.

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

Vì MySQL khá phổ biến và cũng đơn giản nhất, nên bài viết này sử dụng MySQL để giải thích. Các cơ sở dữ liệu quan hệ khác hoạt động tương tự, tải xuống thư viện trình điều khiển MySQL

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

Kết nối với cơ sở dữ liệu

Thông qua hàm sqlx.Open, có thể mở một kết nối cơ sở dữ liệu. Nó nhận hai tham số, tham số đầu tiên là tên trình điều khiển, tham số thứ hai là nguồn dữ liệu (thường gọi là DSN).

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

Tên trình điều khiển là tên được sử dụng khi đăng ký trình điều khiển, cần giữ nhất quán. DSN là địa chỉ kết nối của cơ sở dữ liệu, mỗi loại cơ sở dữ liệu có thể khác nhau. Đối với MySQL, nó như sau

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

Chuẩn bị dữ liệu

sql
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for 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;

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

SET FOREIGN_KEY_CHECKS = 1;

Truy vấn

Truy vấn và ánh xạ kết quả vào cấu trúc

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
   // Một là Get, nhiều là 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)
}

Thêm mới

Thêm dữ liệu mới

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

Cập nhật

Cập nhật dữ liệu

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

Xóa

Xóa dữ liệu

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

Giao dịch

go
func (db *DB) Begin() (*Tx, error) // Bắt đầu một giao dịch
func (tx *Tx) Commit() error // Cam kết một giao dịch
func (tx *Tx) Rollback() error // Lùi lại một giao dịch

Khi bắt đầu một giao dịch, để an toàn thường thêm defer tx.Rollback(). Nếu quá trình xảy ra lỗi, sẽ lùi lại. Nếu giao dịch được cam kết thành công, việc lùi lại này đương nhiên là vô hiệu.

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