日本熟妇hd丰满老熟妇,中文字幕一区二区三区在线不卡 ,亚洲成片在线观看,免费女同在线一区二区

使用Go驅動包Go-MySQL-Driver連接MySQL數據庫

如果您的應用側使用Go語言,且數據庫連接創建頻繁(例如短連接場景)或連接數量較大(大于MySQL數據庫的連接數限制),您可以參考本教程通過Go驅動包Go-MySQL-Driver連接RDS MySQL數據庫,降低連接建立頻率以減少數據庫主線程的開銷。此外,本文還提供連接后操作RDS MySQL數據庫的方法。

說明

Go-MySQL-Driver為Go語言的第三方數據庫驅動包,支持連接MySQL與MariaDB數據庫,詳細信息請參見Go-MySQL-Driver

使用限制

RDS MySQL實例的數據庫版本僅支持5.7、8.0。

準備工作

  • 已下載并安裝Go環境,建議安裝Go 1.20及以上版本。

  • 已將客戶端IP地址添加至RDS實例白名單中。具體操作,請參見設置白名單

    說明

    若您的應用程序部署在阿里云ECS服務器上,且ECS與RDS實例位于同一地域和同一VPC,則無需設置IP白名單。

使用Go-MySQL-Driver連接數據庫

1. 依賴引入

  1. 在Go項目的go.mod文件中,添加go-sql-driver依賴:

    require (
    	github.com/go-sql-driver/mysql v1.8.1
    )
  2. .go文件中導入數據庫驅動的依賴:

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

2. 連接池初始化

.go文件的main方法中初始化連接池并配置以下參數,示例如下:

Addr	// 創建一個數據庫連接
    cfg := mysql.NewConfig()
    cfg.User = "****"  //您需手動替換為實際數據庫用戶名
    cfg.Passwd = "****"  //您需手動替換為實際數據庫密碼
    cfg.Net = "tcp"  //連接類型為TCP,保持默認,無需您手動修改
    cfg.Addr = "rm-2zefwjx1s8156******.mysql.rds.aliyuncs.com:3306"  //您需手動替換為實際MySQL數據庫連接地址和端口號
    cfg.DBName = "****"  //您需手動替換為實際數據庫名稱

    conn, err := mysql.NewConnector(cfg)
    if err != nil {
	panic(err.Error())
    }

    db := sql.OpenDB(conn)
    defer db.Close()

    // 設置連接池參數
    db.SetMaxOpenConns(20)   // 設置連接池中最大打開的連接數, 您可根據實際需要手動調整
    db.SetMaxIdleConns(2)    // 設置連接池中最大空閑的連接數, 您可根據實際需要手動調整
    db.SetConnMaxIdleTime(10 * time.Second)   // 連接在連接池中的最長的空閑時間, 您可根據實際需要手動調整
    db.SetConnMaxLifetime(80 * time.Second)   // 設置連接的最大生命周期, 您可根據實際需要手動調整
說明

RDS MySQL數據庫連接地址和端口的獲取方法,請參見查看和管理實例連接地址和端口

附錄:連接池關鍵參數配置

重要
  • 推薦配置“推薦配置的參數”模塊,降低數據庫運行風險;您可以選擇性配置“可選擇配置的參數模塊”,用以提升使用性能。

  • 為了最大程度地避免潛在的風險和不確定性,您在將新的參數值用于生產環境前,建議至少進行一輪完整的功能測試和性能測試,以確保系統穩定性和可靠性。

推薦配置的參數

參數名

含義

默認值

推薦值

說明

maxIdleTime

設置最大空閑時間(單位:分鐘)。

0

10~30

  • 默認值0表示不超時。

  • 建議根據應用程序的實際需求配置該參數。可通過SetConnMaxIdleTime方法進行設置。

maxLifetime

設置連接的生命周期時間(單位:小時)。

0

1~8

  • 默認值0表示永久存在,即沒有設置最大生命周期。

  • 設置該參數是為防止連接長時間存在,浪費資源。可通過SetConnMaxLifetime方法進行設置。

maxOpen

設置連接池中允許的最大連接數。

0

100

  • 默認值0表示沒有限制。

  • 如果MaxIdleConns大于0且新的MaxOpenConns小于MaxIdleConns,則MaxIdleConns將被縮減以匹配新的MaxOpenConns限制。

  • 建議根據應用程序的實際需求配置該參數。可通過SetMaxOpenConns方法進行設置。

maxIdleCount

設置連接池中允許的最大空閑連接數。

2

20

  • 適當配置該參數可以預留一定數量的連接,快速處理突發增加的數據庫請求。

  • 如果MaxOpenConns大于0但小于新的MaxIdleConns,則新的MaxIdleConns將被縮減以匹配MaxOpenConns的限制。

  • 可通過SetMaxIdleConns方法進行設置。

  • 如果設置傳入的參數n <= 0,則不會保留空閑連接。

readTimeout

I/O讀取的超時時間,您可按需指定為毫秒(ms)、秒(s)或分鐘(m)。

0

10000ms-60000ms

  • 默認值0表示沒有超時限制。建議保持默認值,如果要修改此值,請根據實際業務調整。

  • 該值必須是一個帶有單位后綴的小數,例如“30s”表示30秒,“0.5m”表示0.5分鐘。

writeTimeout

I/O寫入的超時時間,您可按需指定為毫秒(ms)、秒(s)或分鐘(m)。

0

10000ms-60000ms

  • 默認值0表示沒有超時限制。建議保持默認值,如果要修改此值,請根據實際業務調整。

  • 該值必須是一個帶有單位后綴的小數,例如“30s”表示30秒,“0.5m”表示0.5分鐘。

可選擇配置的參數

參數名

含義

默認值

推薦值

說明

timeout

連接建立的超時時間,您可按需指定為毫秒(ms)、秒(s)或分鐘(m)。

默認值是根據操作系統的默認值來設定。

3000ms

  • 該值必須是一個帶有單位后綴的小數,例如“30s”表示30秒,“0.5m”表示0.5分鐘。

  • 創建時的配置,建議設置1~10秒之間,取決于網絡質量高低,以及應用端與服務端的距離。

操作數據庫

創建表

本文以創建一個名為 userinfo 的表為例演示。

_, err = db.Exec("create table  if not exists userinfo( uid int auto_increment, username varchar(20) not null default '', departname varchar(20) not null default '', created varchar(10) not null default '', primary key(uid) );")
if err != nil {
    fmt.Println("create table error ", err)
    return
}

寫入數據

本文以在 userinfo 表中寫入數據為例演示。

方法一:直接寫入數據

result, err := db.Exec("INSERT INTO userinfo (username, departname, created) VALUES (?, ?, ?)", "Linda", "Testing", "2016-06-21")
checkErr(err)
ids, err := result.LastInsertId()
fmt.Println(ids)

方法二:通過綁定參數的方式寫入數據

stmt, err := db.Prepare("INSERT INTO userinfo SET username=?,departname=?,created=?")
res, err := stmt.Exec("James", "Research", "2016-06-17")
id, err := res.LastInsertId()
checkErr(err)
fmt.Println(id)

更新數據

本文以更新userinfo 表中的數據為例演示。

stmt, err = db.Prepare("UPDATE userinfo SET username=?, departname=?, created=? WHERE uid=?")
if err != nil {
    // 如果準備語句時出現錯誤,則進行錯誤處理
}
res, err = stmt.Exec("Robert", "Sales", "2024-09-23", 2)
if err != nil {
    fmt.Println(err)
}
rowCnt, _ := res.RowsAffected()
fmt.Println(rowCnt)

查詢數據

本文以查詢 userinfo 表中username=Linda的數據為例演示。

方法一:直接查詢數據

rows, err := db.Query("SELECT username,departname,created FROM userinfo WHERE username=?", "Linda")
for rows.Next() {
	var username, departname, created string
	if err := rows.Scan(&username, &departname, &created); err != nil {
		fmt.Println(err)
	}
	fmt.Println("username:", username, "departname:", departname, "created:", created)
}

方法二:通過綁定參數的方式執行參數化查詢

stmt, err = db.Prepare("SELECT username,departname,created FROM userinfo WHERE username=?")
if err != nil {
	fmt.Println("prepare error", err)
	return
}
rows, err = stmt.Query("Linda")
if err != nil {
	fmt.Println("query data error", err)
	return
}
defer rows.Close()
for rows.Next() {
	var username, departname, created string
	if err := rows.Scan(&username, &departname, &created); err != nil {
		fmt.Println(err)
	}
	fmt.Println("username:", username, "departname:", departname, "created:", created)
}

刪除數據

本文以刪除userinfo 表中uid=1的數據為例演示。

del_stmt, _ := db.Prepare("DELETE FROM userinfo WHERE uid=?")
del_stmt.Exec(1)

完整示例

package main

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

func main() {
    //創建一個數據庫連接
    cfg := mysql.NewConfig()
    cfg.User = "****"
    cfg.Passwd = "****"
    cfg.Net = "tcp"
    cfg.Addr = "rm-2zefwjx1s8156******.mysql.rds.aliyuncs.com:3306"
    cfg.DBName = "****"

    conn, err := mysql.NewConnector(cfg)
    if err != nil {
       panic(err.Error())
    }

    db := sql.OpenDB(conn)
    defer db.Close()

    // 設置連接池參數
    db.SetMaxOpenConns(20)                 // 設置連接池中最大打開的連接數
    db.SetMaxIdleConns(2)                  // 設置連接池中最大空閑的連接數
    db.SetConnMaxIdleTime(5 * time.Minute) // 設置連接在連接池中的最長的空閑時間
    db.SetConnMaxLifetime(8 * time.Minute) // 設置連接的最大生命周期
    checkErr(err)

    _, err = db.Exec("create table  if not exists userinfo( uid int auto_increment, username varchar(20) not null default '', departname varchar(20) not null default '', created varchar(10) not null default '', primary key(uid) );")
    if err != nil {
       fmt.Println("create table error ", err)
       return
    }

    stmt, err := db.Prepare("INSERT userinfo SET username=?,departname=?,created=?")
    res, err := stmt.Exec("zhja", "研發", "2016-06-17")
    id, err := res.LastInsertId()
    checkErr(err)
    fmt.Println(id)

    result, err := db.Exec("INSERT INTO userinfo (username, departname, created) VALUES (?, ?, ?)", "lily", "銷售", "2016-06-21")
    checkErr(err)
    ids, err := result.LastInsertId()
    fmt.Println(ids)

    del_stmt, _ := db.Prepare("DELETE FROM userinfo WHERE uid=?")
    del_stmt.Exec(1)

    stmt, err = db.Prepare("UPDATE userinfo SET username=?, departname=?, created=? WHERE uid=?")
    if err != nil {
       // 處理錯誤
    }
    res, err = stmt.Exec("lisi", "測試", "2024-09-23", 2)
    if err != nil {
       fmt.Println(err)
    }
    rowCnt, _ := res.RowsAffected()
    fmt.Println(rowCnt)

    rows, err := db.Query("SELECT username,departname,created FROM userinfo WHERE username=?", "lisi")
    for rows.Next() {
       var username, departname, created string
       if err := rows.Scan(&username, &departname, &created); err != nil {
          fmt.Println(err)
       }
       fmt.Println("username:", username, "departname:", departname, "created:", created)
    }

    stmt, err = db.Prepare("SELECT username,departname,created FROM userinfo WHERE username=?")
    if err != nil {
       fmt.Println("prepare error", err)
       return
    }
    rows, err = stmt.Query("lisi")
    if err != nil {
       fmt.Println("query data error", err)
       return
    }
    defer rows.Close()
    for rows.Next() {
       var username, departname, created string
       if err := rows.Scan(&username, &departname, &created); err != nil {
          fmt.Println(err)
       }
       fmt.Println("username:", username, "departname:", departname, "created:", created)
    }

}

func checkErr(err error) {
    if err != nil {
       panic(err)
    }
}

相關文檔