Golang Package-database/sql

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

一、匯入庫

import (    "database/sql"    _ "github.com/lib/pq")

 

二、串連DB

func main() {    db, err := sql.Open("postgres", "user=pqgotest dbname=pqgotest sslmode=verify-full")    /*db, err := sql.Open("postgres",           "postgres://pqgotest:password@localhost/pqgotest?sslmode=verify-full")*/    if err != nil {        log.Fatal(err)    }    defer db.Close()}

        sql.Open的第一個參數是driver名稱,第二個參數是driver串連資料庫的資訊。DB不是串連,並且只有當需要使用時才會建立串連,如果想立即驗證串連,需要用Ping()方法,如下:

err = db.Ping()if err != nil {    // do something here}

        sql.DB的設計就是用來作為長串連使用的。不要頻繁Open, Close。比較好的做法是,為每個不同的datastore建一個DB對象,保持這些對象Open。如果需要短串連,那麼把DB作為參數傳入function,而不要在function中Open, Close。

        在database/sql中有一個很基本的串連池,當需要串連,且串連池中沒有可用串連時,新的串連就會被建立;如果長時間保持空閑串連,可能會導致db timeout。可以設定SetMaxIdleConns和SetMaxOpenConns,也就是最大空閑串連和最大串連數,分別是下面這兩個函數:

db.SetMaxIdleConns(n)db.SetMaxOpenConns(n)

 

三、查詢DB

(1)一般查詢Query

var name, sex stringrows, err := db.Query("select name, sex from user where id = $1 ", 1)if err != nil {fmt.Println(err)}defer rows.Close()for rows.Next() {err := rows.Scan(&name, &sex)if err != nil {fmt.Println(err)}}err = rows.Err()if err != nil {fmt.Println(err)}fmt.Println("name:", name, "sex:", sex)

        上面代碼的過程為:db.Query()表示向資料庫發送一個query,defer rows.Close()非常重要(關閉串連),遍曆rows使用rows.Next(),把遍曆到的資料存入變數使用rows.Scan(),遍曆完成後檢查error。有幾點需要注意:

        (1) 檢查遍曆是否有error
        (2) 結果集(rows)未關閉前,底層的串連處於繁忙狀態。當遍曆讀到最後一條記錄時,會發生一個內部EOF錯誤,自動調用rows.Close(),但是如果提前退出迴圈,rows不會關閉,串連不會回到串連池中,串連也不會關閉。所以手動關閉非常重要。rows.Close()可以多次調用,是無害操作。

(2)單條查詢QueryRow

var name stringerr = db.QueryRow("select name from user where id = $1", 222).Scan(&name)if err != nil {    if err == sql.ErrNoRows {        // there were no rows, but otherwise no error occurred    } else {        log.Fatal(err)    }}fmt.Println(name)

 

四、增刪改Exec

Prepared Statements and Connection
      在資料庫層面,Prepared Statements是和單個資料庫連接綁定的。用戶端發送一個有預留位置的statement到服務端,伺服器返回一個statement ID,然後用戶端發送ID和參數來執行statement。

       在GO中,串連不直接暴露,你不能為串連綁定statement,而是只能為DB或Tx綁定。database/sql包有自動重試等功能。當你產生一個Prepared Statement

      (1)自動在串連池中綁定到一個空閑串連
      (2)Stmt對象記住綁定了哪個串連
      (3)執行Stmt時,嘗試使用該串連。如果不可用,例如串連被關閉或繁忙中,會自動re-prepare,綁定到另一個串連。
       這就導致在高並發的情境,過度使用statement可能導致statement泄漏,statement持續重複prepare和re-prepare的過程,甚至會達到伺服器端statement數量上限。

有些情境不適合用statement

      (1)資料庫不支援。例如Sphinx,MemSQL。他們支援MySQL wire protocol, 但不支援"binary" protocol。
       (2)statement不需要重用很多次,並且有其他方法保證安全。

stmt, err := db.Prepare("insert into user(name, sex)values($1,$2)")if err != nil {fmt.Println(err)}rs, err := stmt.Exec("go-test", 12)if err != nil {fmt.Println(err)}//可以獲得影響行數affect, err := rs.RowsAffected()fmt.Println("affect ", affect ," rows")

 

五、事務

tx, err := db.Begin()if err != nil {    log.Fatal(err)}defer tx.Rollback()stmt, err := tx.Prepare("INSERT INTO foo VALUES ($1)")if err != nil {    log.Fatal(err)}for i := 0; i < 10; i++ {    _, err = stmt.Exec(i)    if err != nil {        log.Fatal(err)    }}err = tx.Commit()if err != nil {    log.Fatal(err)}defer stmt.Close() //runs here!

        db.Begin()開始事務,Commit() Rollback()關閉事務。Tx從串連池中取出一個串連,在關閉之前都是使用這個串連。Tx不能和DB層的BEGIN, COMMIT混合使用

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.