golang數據庫操做初體驗

在golang中,提供了標準的數據庫接口database/sql包,作過數據庫開發的應該知道,不一樣的數據庫有不一樣的數據庫驅動。好比mysql等,咱們能夠去找 https://golang.org/s/sqldrivers 這裏找自已須要的驅動,這裏我就以mysql的驅動爲例,用的是go-sql-driver這個。mysql

安裝

直接執行go get,而後會下載到你的$GOPATH中,若是用的go mod也同樣,只不過下載的路徑不同。git

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

導入驅動

database/sql這個包是要導入的,而後導入go-sql-driver,包前面的 「_"表示執行包的init函數,函數init裏面直接將自已註冊到database/sql包中,而後就能用這個包裏面的方法訪問數據庫了。github

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

func init() {
    sql.Register("mysql", &MySQLDriver{})
}

鏈接數據庫

type dbObj struct {
    db *sql.DB
}

func (d *dbObj) Open() *sql.DB{
    var err error
    d.db, err = sql.Open("mysql", "lc:111111@/test")
    if err != nil {
        panic(err)
    }
    return d.db
}

使用 sql.Open 來鏈接數據庫,可是這個只是返回一個數據庫的抽象實例,並無真正的鏈接到數據庫中,在後續的對數據庫的操做中才會真正去網絡鏈接,若是要立刻驗證,能夠用 db.ping().golang

sql.Open的簽名以下:sql

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

它接受兩個參數:數據庫

  • driverName就是咱們在init函數註冊的那個名字
  • dataSourceName爲數據庫連接dsn,格式爲 [username[:password]@][protocol[(address)]]/dbname[?param1=value1&...&paramN=valueN]

示例

來點基本的CURD操做,仍是挺簡單的。網絡

package db

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

type  userInfo struct {
    id int
    orgcode string
    name string
    version int
}

type dbObj struct {
    db *sql.DB
}

func (d *dbObj) Open() *sql.DB{
    var err error
    d.db, err = sql.Open("mysql", "lc:111111@/test")
    if err != nil {
        panic(err)
    }
    return d.db
}
func (d *dbObj) Close(){
    d.Close()
}


func SelectAll() {
    dbc :=&dbObj{}
    db := dbc.Open()
    defer db.Close()

    stmt ,_ :=db.Prepare("SELECT orgcode,`name` FROM  userinfo WHERE id > ?")
    rows, _ :=stmt.Query(0) //query爲多行
    defer rows.Close()
    user :=&userInfo{}

    for rows.Next() {
        err :=rows.Scan(&user.orgcode,&user.name)
        if err != nil {
            log.Fatal(err)
        }
        fmt.Println(user.orgcode , ":", user.name)
    }
}

func Select() {
    dbc :=&dbObj{}
    db := dbc.Open()
    defer db.Close()

    stmt ,_ :=db.Prepare("SELECT orgcode,`name` FROM  userinfo WHERE ID= ?")
    rows :=stmt.QueryRow(1008) //QueryRow爲單行

    user :=&userInfo{}


    err :=rows.Scan(&user.orgcode,&user.name)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(user.orgcode , ":", user.name)

}

func Insert() {
    dbc :=&dbObj{}
    db := dbc.Open()
    defer db.Close()

    result, err :=db.Exec("INSERT  userinfo (orgcode,imei,`name`) VALUE(?,?,?)","cccc",1009,"cccc")
    if err != nil {
        log.Fatal(err)
    }
    rowsaffected,err :=  result.RowsAffected()
    if err != nil {
        fmt.Printf("獲取受影響行數失敗,err:%v",err)
        return
    }
    fmt.Println("受影響行數:" ,rowsaffected )
}

func Delete() {
    dbc :=&dbObj{}
    db := dbc.Open()
    defer db.Close()

    result, err :=db.Exec("DELETE FROM userinfo WHERE id=?",1009)
    if err != nil {
        log.Fatal(err)
    }
    rowsaffected,err :=  result.RowsAffected()
    if err != nil {
        fmt.Printf("獲取受影響行數失敗,err:%v",err)
        return
    }
    fmt.Println("受影響行數:" ,rowsaffected )
}

func Update() {
    dbc :=&dbObj{}
    db := dbc.Open()
    defer db.Close()

    result, err :=db.Exec("UPDATE userinfo SET `name`= ? WHERE id=?", "lcbbb",1008)
    if err != nil {
        log.Fatal(err)
    }

    rowsaffected,err :=  result.RowsAffected()
    if err != nil {
        fmt.Printf("獲取受影響行數失敗,err:%v",err)
        return
    }
    fmt.Println("受影響行數:" ,rowsaffected )
}



func Transaction() {
    dbc :=&dbObj{}
    db := dbc.Open()
    defer db.Close()

    tx ,_:=db.Begin()
    tx.Exec("UPDATE userinfo SET `name`= ? WHERE id=?", "lcaaa",1007)
    result, err :=tx.Exec("UPDATE userinfo SET `name`= ? WHERE id=?", "lcbbb",1008)
    if err != nil {
        log.Fatal(err)
    }
    tx.Commit() //提交事務
    rowsaffected,err :=  result.RowsAffected()
    if err != nil {
        fmt.Printf("獲取受影響行數失敗,err:%v",err)
        return
    }
    fmt.Println("受影響行數:" ,rowsaffected )
}


func ConcurrenceUpdate() {
    dbc :=&dbObj{}
    db := dbc.Open()
    defer db.Close()

    getone :=func(db *sql.DB,id int) *userInfo{


        stmt ,_ :=db.Prepare("SELECT orgcode,`name`,version FROM  userinfo WHERE ID= ?")
        rows :=stmt.QueryRow(id) //

        user :=&userInfo{}


        err :=rows.Scan(&user.orgcode,&user.name, &user.version)
        if err != nil {
            log.Fatal(err)
        }

        return user

    }

    udateone :=func(db *sql.DB,name string,id int,version int){
        result, err :=db.Exec("UPDATE userinfo SET `name`= ?, version=version+1 WHERE id=? AND version=?", name,id,version)
        if err != nil {
            log.Fatal(err)
        }

        rowsaffected,err :=  result.RowsAffected()
        if err != nil {
            fmt.Printf("併發更新獲取受影響行數失敗,err:%v",err)
            return
        }
        fmt.Println("併發更新受影響行數:" ,rowsaffected )
    }

    num :=10
    for i:=0; i<num ;i++{
        go func(){
            u :=getone(db,1008)
            fmt.Printf("獲取數據:%v\r\n",u)
            udateone(db,"lc併發更新測試", 1008,u.version)
        }()
    }

    select{}
}

以上只是一些基本的數據庫操做,像鏈接池等尚未作,這個等後續看了再去寫。併發

相關文章
相關標籤/搜索