go-sql-driver 使用
go-sql-driver 是go用來鏈接mysql數據庫的包。截止當前時間github上star 9.3k
環境:
go | go-sql-driver |
---|---|
go1.13.5 | v1.5.0 |
安裝:
使用go mod 進行安裝
在go.mod 中加入:
module github.com/luslin/tools
go 1.13
require (
github.com/Shopify/sarama v1.26.1
github.com/gin-gonic/gin v1.6.2
github.com/go-redis/redis v6.15.7+incompatible
github.com/go-sql-driver/mysql v1.5.0 // 這一行
github.com/json-iterator/go v1.1.9
github.com/tidwall/gjson v1.6.0
go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738
)
然後執行go mod download 就可以可。 我的GOPROXY設置爲https://goproxy.cn,direct
使用:
我的數據表結構: umeta_id int, user_id int, meta_key vchar, meta_value vchar
a、導入包:
import (
"context"
"database/sql"
"fmt"
_ "github.com/go-sql-driver/mysql"
"testing"
)
b、創建公共變量,結構體,處理失敗方法
type Wp_usermeta struct {
Umeta_id int `json:"umeta_id"`
User_id int `json:"user_id"`
Meta_key string `json:"meta_key"`
Meta_value string `json:"meta_value"`
}
var (
db *sql.DB
err error
)
func painc_err(err error) {
if err != nil {
panic(err)
}
}
c、初始化db
// The returned DB is safe for concurrent use by multiple goroutines
// and maintains its own pool of idle connections. Thus, the Open
// function should be called just once. It is rarely necessary to
// close a DB.
// db是線程安全的,並且在內部維護了數據池。open方法應只調用一次,並且沒必要關閉
func init() {
// 格式:username:password@鏈接協議(ip:port)/db?參數
db, err = sql.Open("mysql", "root:fstxlab@2017!@tcp(123.57.174.21:3306)/horizon?charset=utf8")
painc_err(err)
}
d、curd
1、查詢單條記錄
func TestQueryRow(t *testing.T) {
stmt, err := db.Prepare("select * from wp_usermeta where umeta_id = ?")
defer stmt.Close()
painc_err(err)
res:= stmt.QueryRow(12)
var usermeta Wp_usermeta
err = res.Scan(&usermeta.Umeta_id, &usermeta.User_id, &usermeta.Meta_key, &usermeta.Meta_value)
painc_err(err)
fmt.Println(usermeta)
}
2、查詢多條記錄
func TestQueryRows(t *testing.T) {
stmt, err := db.Prepare("select * from wp_usermeta where umeta_id < ?")
defer stmt.Close()
painc_err(err)
res, err := stmt.Query(12)
defer res.Close()
painc_err(err)
for res.Next() {
var usermeta Wp_usermeta
err = res.Scan(&usermeta.Umeta_id, &usermeta.User_id, &usermeta.Meta_key, &usermeta.Meta_value)
painc_err(err)
fmt.Println(usermeta)
}
}
3、插入數據
func TestInsert(t *testing.T) {
stmt, err := db.Prepare("insert into wp_usermeta(user_id,meta_key,meta_value) value (?,?,?)")
painc_err(err)
defer stmt.Close()
res, err := stmt.Exec(2,"test3","test4")
painc_err(err)
row_num, err := res.RowsAffected()
painc_err(err)
fmt.Println(row_num)
}
4、修改數據
func TestUpdate(t *testing.T) {
stmt, err := db.Prepare("update wp_usermeta set user_id=? where user_id=?")
painc_err(err)
defer stmt.Close()
res, err := stmt.Exec(1,2)
painc_err(err)
row_num, err := res.RowsAffected()
painc_err(err)
fmt.Println(row_num)
}
5、刪除數據
func TestDelete(t *testing.T) {
stmt, err := db.Prepare("delete from wp_usermeta where umeta_id=?")
painc_err(err)
defer stmt.Close()
res, err := stmt.Exec(27)
painc_err(err)
row_num, err := res.RowsAffected()
painc_err(err)
fmt.Println(row_num)
}
e、事務
func TestTxn(t *testing.T) {
txn := sql.TxOptions{sql.LevelRepeatableRead,false}
tx, err := db.BeginTx(context.Background(),&txn)
painc_err(err)
stmt1, err := tx.Prepare("delete from wp_usermeta where umeta_id=?")
painc_err(err)
defer stmt1.Close()
res, err := stmt1.Exec(30)
painc_err(err)
row_num, err := res.RowsAffected()
painc_err(err)
fmt.Println(row_num)
//err = tx.Commit()
//painc_err(err)
err = tx.Rollback()
painc_err(err)
}
Commit不能與Rollback同時使用
事務屬性的結構:
type TxOptions struct {
// Isolation is the transaction isolation level.
// If zero, the driver or database's default level is used.
Isolation IsolationLevel
ReadOnly bool
}
Isolation 代表事務隔離級別,有以下幾種:
LevelDefault IsolationLevel = iota 默認
LevelReadUncommitted
LevelReadCommitted
LevelWriteCommitted
LevelRepeatableRead
LevelSnapshot
LevelSerializable
LevelLinearizable
參考:https://www.cnblogs.com/wyaokai/p/10921323.html
1、髒讀:事務A讀取了事務B更新的數據,然後B回滾操作,那麼A讀取到的數據是髒數據
2、不可重複讀:事務 A 多次讀取同一數據,事務 B 在事務A多次讀取的過程中,對數據作了更新並提交,導致事務A多次讀取同一數據時,結果 不一致。
3、幻讀:系統管理員A將數據庫中所有學生的成績從具體分數改爲ABCDE等級,但是系統管理員B就在這個時候插入了一條具體分數的記錄,當系統管理員A改結束後發現還有一條記錄沒有改過來,就好像發生了幻覺一樣,這就叫幻讀。
小結:不可重複讀的和幻讀很容易混淆,不可重複讀側重於修改,幻讀側重於新增或刪除。解決不可重複讀的問題只需鎖住滿足條件的行,解決幻讀需要鎖表
事務隔離級別 | 髒讀 | 不可重複讀 | 幻讀 |
---|---|---|---|
讀未提交ReadUncommitted | 是 | 是 | 是 |
不可重複讀ReadCommitted | 否 | 是 | 是 |
可重複讀RepeatableRead | 否 | 否 | 是 |
串行化Serializable | 否 | 否 | 否 |