在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&...¶mN=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{}
}
以上只是一些基本的資料庫操作,像連接池等還沒有做,這個等后續看了再去寫,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/51180.html
標籤:Go
上一篇:golang的io.copy使用
下一篇:golang自定義error
