Skip to content

MySQL

Mysql 是當下最流行的開源關系型數據庫,具體的 sql 知識這裡不會做過多的贅述,如果你不會請先自行學習,本文只是簡單講解如何利用 go 進行 sql 操作。在項目中的話一般不會直接使用驅動來進行數據庫操作,而是會使用 ORM 框架,這裡使用的是sqlx庫,是對標准sql庫的增強,沒有 ORM 功能那麼豐富但是勝在簡潔。如果你想使用 ORM,可以去了解GormXormEnt這些庫。

依賴

下載sqlx

bash
$ go get github.com/jmoiron/sqlx

sqlx或者說標准庫database/sql支持的數據庫不止 MySQL,任何實現了driver.Driver接口的類型都支持,比如:

  • PostgreSQL
  • Oracle
  • MariaDB
  • SQLite
  • 等其他關系數據庫

要使用對應的數據庫,就需要實現數據庫驅動,驅動可以是你自己寫的,也可以是第三方庫,在使用之前你就要先使用sql.Register注冊驅動,然後才能使用。不過一般下載的驅動庫都會自動注冊驅動,不需要你來手動注冊。

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

由於 MySQL 比較流行,也最為簡單,所以本文采用 MySQL 來講解,其他關系數據庫操作起來都是大差不大差的,下載 MySQL 驅動庫

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

連接到數據庫

通過sqlx.Open函數,就可以打開一個數據庫連接,它接受兩個參數,第一個是驅動名稱,第二個就是數據源(一般簡稱 DSN)。

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

驅動名稱就是注冊驅動時使用的名稱,需要保持一致,DSN 就是數據庫的連接地址,每種數據庫都可能會不一樣,對於 MySQL 而言就是下面這樣

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

准備數據

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;

查詢

查詢,並將結果映射到結構體中

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
   //查詢一個是Get,多個是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)
}

新增

新增數據

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

更新

更新數據

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

刪除

刪除數據

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

事務

go
func (db *DB) Begin() (*Tx, error) //開始一個事務
func (tx *Tx) Commit() error //提交一個事務
func (tx *Tx) Rollback() error //回滾一個事務

當開啟一個事務後,為了保險都會加一句defer tx.Rollback(),如果如果過程出錯了,就會回滾,要是事務成功提交了,這個回滾自然是無效的。

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學習網由www.golangdev.cn整理維護