golang數據庫操作初體驗


在golang中,提供了標准的數據庫接口database/sql包,做過數據庫開發的應該知道,不同的數據庫有不同的數據庫驅動。比如mysql等,我們可以去找 https://golang.org/s/sqldrivers 這里找自已需要的驅動,這里我就以mysql的驅動為例,用的是go-sql-driver這個。

安裝

直接執行go get,然后會下載到你的$GOPATH中,如果用的go mod也一樣,只不過下載的路徑不一樣。

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

導入驅動

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

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().

sql.Open的簽名如下:

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{}
}

以上只是一些基本的數據庫操作,像連接池等還沒有做,這個等后續看了再去寫。


免責聲明!

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



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