1. 程式人生 > >golang連線mysql資料庫實現增刪改查

golang連線mysql資料庫實現增刪改查

golang本身沒有提供連線mysql的驅動,但是定義了標準介面供第三方開發驅動。這裡連線mysql可以使用第三方庫,第三方庫推薦使用https://github.com/Go-SQL-Driver/MySQL這個驅動,更新維護都比較好。下面演示下具體的使用,完整程式碼示例可以參考最後。

下載驅動

sudo go get github.com/go-sql-driver/mysql 如果提示這樣的失敗資訊:cannot download, $GOPATH not set. For more details see: go help gopath,可以使用如下命令解決

sudo env GOPATH=/Users/chenjiebin/golang go get github.com/go-sql-driver/mysql GOPATH的值根據自行環境進行替換。

建立測試表

在mysql test庫中建立測試表

 程式碼如下 複製程式碼
CREATE TABLE IF NOT EXISTS `test`.`user` (  `user_id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '使用者編號',  `user_name` VARCHAR(45) NOT NULL COMMENT '使用者名稱稱',  `user_age` TINYINT(3) UNSIGNED NOT NULL DEFAULT 0 COMMENT '使用者年齡',  `user_sex` TINYINT(3) UNSIGNED NOT NULL DEFAULT 0 COMMENT '使用者性別',  PRIMARY KEY (`user_id`))  ENGINE = InnoDB  AUTO_INCREMENT = 1  DEFAULT CHARACTER SET = utf8  COLLATE = utf8_general_ci  COMMENT = '使用者表'

資料庫連線

資料庫連線使用datebase/sql Open函式進行連線  

 程式碼如下 複製程式碼

db, err := sql.Open("mysql", "user:[email protected](localhost:5555)/dbname?charset=utf8") 其中連線引數可以有如下幾種形式:

[email protected](/path/to/socket)/dbname?charset=utf8 user:[email protected](localhost:5555)/dbname?charset=utf8 user:

[email protected]/dbname user:[email protected]([de:ad:be:ef::ca:fe]:80)/dbname

通常我們都用第二種。

插入操作  

 程式碼如下 複製程式碼
stmt, err := db.Prepare(`INSERT user (user_name,user_age,user_sex) values (?,?,?)`) checkErr(err) res, err := stmt.Exec("tony", 20, 1) checkErr(err) id, err := res.LastInsertId() checkErr(err) fmt.Println(id)

這裡使用結構化操作,不推薦使用直接拼接sql語句的方法。

查詢操作  

 程式碼如下 複製程式碼
rows, err := db.Query("SELECT * FROM user") checkErr(err)   for rows.Next() {     var userId int     var userName string     var userAge int     var userSex int     rows.Columns()     err = rows.Scan(&userId, &userName, &userAge, &userSex)     checkErr(err)     fmt.Println(userId)     fmt.Println(userName)     fmt.Println(userAge)     fmt.Println(userSex) }

這裡查詢的方式使用宣告4個獨立變數userId、userName、userAge、userSex來儲存查詢出來的每一行的值。在實際開發中通常會封裝資料庫的操作,對這樣的查詢通常會考慮返回字典型別。

 程式碼如下 複製程式碼

//構造scanArgs、values兩個陣列,scanArgs的每個值指向values相應值的地址 columns, _ := rows.Columns() scanArgs := make([]interface{}, len(columns)) values := make([]interface{}, len(columns)) for i := range values {     scanArgs[i] = &values[i] }   for rows.Next() {     //將行資料儲存到record字典     err = rows.Scan(scanArgs...)     record := make(map[string]string)     for i, col := range values {         if col != nil {             record[columns[i]] = string(col.([]byte))         }     }     fmt.Println(record) } 修改操作

stmt, err := db.Prepare(`UPDATE user SET user_age=?,user_sex=? WHERE user_id=?`) checkErr(err) res, err := stmt.Exec(21, 2, 1) checkErr(err) num, err := res.RowsAffected() checkErr(err) fmt.Println(num) 刪除操作

stmt, err := db.Prepare(`DELETE FROM user WHERE user_id=?`) checkErr(err) res, err := stmt.Exec(1) checkErr(err) num, err := res.RowsAffected() checkErr(err) fmt.Println(num)

修改和刪除操作都比較簡單,同插入資料類似,只是使用RowsAffected來獲取影響的資料行數。

完整程式碼

 程式碼如下 複製程式碼
package main   import (     "database/sql"     "fmt"     _ "github.com/go-sql-driver/mysql" )   func main() {     insert() }   //插入demo func insert() {     db, err := sql.Open("mysql", "root:@/test?charset=utf8")     checkErr(err)       stmt, err := db.Prepare(`INSERT user (user_name,user_age,user_sex) values (?,?,?)`)     checkErr(err)     res, err := stmt.Exec("tony", 20, 1)     checkErr(err)     id, err := res.LastInsertId()     checkErr(err)     fmt.Println(id) }   //查詢demo func query() {     db, err := sql.Open("mysql", "root:@/test?charset=utf8")     checkErr(err)       rows, err := db.Query("SELECT * FROM user")     checkErr(err)       //普通demo     //for rows.Next() {     //    var userId int     //    var userName string     //    var userAge int     //    var userSex int       //    rows.Columns()     //    err = rows.Scan(&userId, &userName, &userAge, &userSex)     //    checkErr(err)       //    fmt.Println(userId)     //    fmt.Println(userName)     //    fmt.Println(userAge)     //    fmt.Println(userSex)     //}       //字典型別     //構造scanArgs、values兩個陣列,scanArgs的每個值指向values相應值的地址     columns, _ := rows.Columns()     scanArgs := make([]interface{}, len(columns))     values := make([]interface{}, len(columns))     for i := range values {         scanArgs[i] = &values[i]     }       for rows.Next() {         //將行資料儲存到record字典         err = rows.Scan(scanArgs...)         record := make(map[string]string)         for i, col := range values {             if col != nil {                 record[columns[i]] = string(col.([]byte))             }         }         fmt.Println(record)     } }   //更新資料 func update() {     db, err := sql.Open("mysql", "root:@/test?charset=utf8")     checkErr(err)       stmt, err := db.Prepare(`UPDATE user SET user_age=?,user_sex=? WHERE user_id=?`)     checkErr(err)     res, err := stmt.Exec(21, 2, 1)     checkErr(err)     num, err := res.RowsAffected()     checkErr(err)     fmt.Println(num) }   //刪除資料 func remove() {     db, err := sql.Open("mysql", "root:@/test?charset=utf8")     checkErr(err)       stmt, err := db.Prepare(`DELETE FROM user WHERE user_id=?`)     checkErr(err)     res, err := stmt.Exec(1)     checkErr(err)     num, err := res.RowsAffected()     checkErr(err)     fmt.Println(num) }   func checkErr(err error) {     if err != nil {         panic(err)     } }

小結

整體上來說都比較簡單,就是查詢那邊使用字典來儲存返回資料比較複雜一些。既然說到資料庫連線,通常應用中都會使用連線池來減少連線開銷,關於連線池下次整理一下再放上來。