Go操作數據庫之MySQL


 

安裝mysql驅動:

go get -u github.com/go-sql-driver/mysql

初始化模塊

go mod init m

執行
go mod tidy

 

導入包:

package main

import (
"fmt"
"database/sql"
_ "github.com/go-sql-driver/mysql"
)

 

獲得鏈接:

package main

import (
    "database/sql"
    _ "github.com/go-sql-driver/mysql"
    "time"
)

func main() {
    db, err := sql.Open("mysql", "root:123456@/go_db")
    if err != nil {
        panic(err)
    }
    print(db)
   // 最大連接時長
    db.SetConnMaxLifetime(time.Minute * 3)
   // 最大連接數
    db.SetMaxOpenConns(10)
    // 空閑連接數
    db.SetMaxIdleConns(10)
}

初始化連接

Open函數可能只是驗證其參數格式是否正確,實際上並不創建與數據庫的連接。如果要檢查數據源的名稱是否真實有效,應該調用Ping方法。

返回的DB對象可以安全地被多個goroutine並發使用,並且維護其自己的空閑連接池。因此,Open函數應該僅被調用一次,很少需要關閉這個DB對象。

package main

import (
    "database/sql"
    "fmt"
    _ "github.com/go-sql-driver/mysql"
)

// 定義一個全局對象db
var db2 *sql.DB

// 定義一個初始化數據庫的函數
func initDB() (err error) {
    dsn := "root:123456@tcp(127.0.0.1:3306)/go_db?charset=utf8mb4&parseTime=True"
    // 不會校驗賬號密碼是否正確
    // 注意!!!這里不要使用:=,我們是給全局變量賦值,然后在main函數中使用全局變量db
    db2, err = sql.Open("mysql", dsn)
    if err != nil {
        return err
    }
    // 嘗試與數據庫建立連接(校驗dsn是否正確)
    err = db2.Ping()
    if err != nil {
        return err
    }
    return nil
}

func main() {
    err := initDB() // 調用輸出化數據庫的函數
    if err != nil {
        fmt.Printf("初始化失敗!,err:%v\n", err)
        return
    }else{
        fmt.Printf("初始化成功")
    }
}

 

當行查詢:

單行查詢db.QueryRow()執行一次查詢,並期望返回最多一行結果(即Row)。QueryRow總是返回非nil的值,直到返回值的Scan方法被調用時,才會返回被延遲的錯誤。

 

定義結構體:

type user struct {
    id int
    username string
    password string
}
// 查詢一條用戶數據
func queryRowDemo() {
sqlStr := "select id, username, password from user_tbl where id=?"
var u user
// 確保QueryRow之后調用Scan方法,否則持有的數據庫鏈接不會被釋放
err := db.QueryRow(sqlStr, 1).Scan(&u.id, &u.username, &u.password)
if err != nil {
fmt.Printf("scan failed, err:%v\n", err)
return
}
fmt.Printf("id:%d name:%s age:%s\n", u.id, u.username, u.password)
}
func main() {
err := initDB() // 調用輸出化數據庫的函數
if err != nil {
fmt.Printf("初始化失敗!,err:%v\n", err)
return
}else{
fmt.Printf("初始化成功")
}
queryRowDemo()
}

查詢多行

多行查詢db.Query()執行一次查詢,返回多行結果(即Rows),一般用於執行select命令。參數args表示query中的占位參數。

// 查詢多條數據示例
func queryMultiRow() {
sqlStr := "select id, username, password from user_tbl where id > ?"
rows, err := db.Query(sqlStr, 0)
if err != nil {
fmt.Printf("query failed, err:%v\n", err)
return
}
// 非常重要:關閉rows釋放持有的數據庫鏈接
defer rows.Close()

// 循環讀取結果集中的數據
for rows.Next() {
var u user
err := rows.Scan(&u.id, &u.username, &u.password)
if err != nil {
fmt.Printf("scan failed, err:%v\n", err)
return
}
fmt.Printf("id:%d username:%s password:%s\n", u.id, u.username, u.password)
}
}

插入,更新和刪除操作都使用Exec方法

func (db *DB) Exec(query string, args ...interface{}) (Result, error)

 

新增:
// 插入數據
func insertData() {
sqlStr := "insert into user_tbl(username,password) values (?,?)"
ret, err := db.Exec(sqlStr, "張三", "zs123")
if err != nil {
fmt.Printf("insert failed, err:%v\n", err)
return
}
theID, err := ret.LastInsertId() // 新插入數據的id
if err != nil {
fmt.Printf("get lastinsert ID failed, err:%v\n", err)
return
}
fmt.Printf("insert success, the id is %d.\n", theID)
}


刪除:
func delData() {
sql := "delete from user_tbl where id =?"
ret, err := db.Exec(sql, "1")
if err != nil {
fmt.Printf("刪除失敗, err:%v\n", err)
return
}
rows, err := ret.RowsAffected()
if err != nil {
fmt.Printf("刪除行失敗, err:%v\n", err)
return
}
fmt.Printf("刪除成功, 刪除的行數:%d.\n", rows)
}


更新:
func updateData() {
sql := "update user_tbl set username=?, password=? where id=?"
ret, err := db.Exec(sql, "kite2", "kite123", "2")
if err != nil {
fmt.Printf("更新失敗, err:%v\n", err)
return
}
rows, err := ret.RowsAffected()
if err != nil {
fmt.Printf("更新行失敗, err:%v\n", err)
return
}
fmt.Printf("更新成功, 更新的行數:%d.\n", rows)
}

 

 

注意點:

1.表名不能作為占位符使用

"DELETE FROM `?` WHERE created_date BETWEEN ? AND ?" 

ret, err := db3.Exec(sql, tableName, startDate, endDate)

2.dsn中用戶名和密碼 如果包含特殊字符:!@#^*等,需要進行urlencode處理

url.QueryEscape

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM