友情提示:此篇文章大約須要閱讀 14分鐘5秒,不足之處請多指教,感謝你的閱讀。 訂閱本站mysql
sqlx
是 Go 的軟件包,它在出色的內置database/sql
軟件包的基礎上提供了一組擴展。git
該庫兼容sql
原生包,同時又提供了更爲強大的、優雅的查詢、插入函數。github
該庫提供四個處理類型,分別是:sql
sqlx.DB
– 相似原生的 sql.DB
;sqlx.Tx
– 相似原生的 sql.Tx
;sqlx.Stmt
– 相似原生的 sql.Stmt
, 準備 SQL 語句操做;sqlx.NamedStmt
– 對特定參數命名並綁定生成 SQL 語句操做。提供兩個遊標類型,分別是:數據庫
sqlx.Rows
– 相似原生的 sql.Rows
, 從 Queryx
返回;sqlx.Row
– 相似原生的 sql.Row
, 從 QueryRowx
返回。go get github.com/jmoiron/sqlx
// 初始化數據庫 func initMySQL() (err error) { dsn := "root:password@tcp(127.0.0.1:3306)/database" db, err = sqlx.Open("mysql", dsn) if err != nil { fmt.Printf("connect server failed, err:%v\n", err) return } db.SetMaxOpenConns(200) db.SetMaxIdleConns(10) return }
SetMaxOpenConns
和 SetMaxIdleConns
分別爲設置最大鏈接數和最大空閒數。數組
在這裏提早聲明一個用戶結構體 user
,將 *sqlx.DB
做爲一個全局變量使用,固然也要提早引用 MySQL 的驅動包,以下設計:tcp
import ( "fmt" _ "github.com/go-sql-driver/mysql" "github.com/jmoiron/sqlx" ) var db *sqlx.DB type user struct { Id int `db:"id"` Age int `db:"age"` Name string `db:"name"` }
查詢一行數據使用sqlx
庫中的Get
函數實現:函數
func (db *DB) Get(dest interface{}, query string, args ...interface{}) error
dest
是用戶聲明變量接收查詢結果,query
爲查詢 SQL 語句,args
爲綁定參數的賦值。post
// 查詢一行數據 func queryRow() { sqlStr := "SELECT id, name, age FROM user WHERE id = ?" var u user if err := db.Get(&u, sqlStr, 1); err != nil { fmt.Printf("get data failed, err:%v\n", err) return } fmt.Printf("id:%d, name:%s, age:%d\n", u.Id, u.Name, u.Age) }
而查詢多行數據則使用的是Select
函數:debug
func (db *DB) Select(dest interface{}, query string, args ...interface{}) error
使用Select
函數進行查詢的時候,須要先聲明一個結構體數組接收映射過來的數據:
// 查詢多行數據 func queryMultiRow() { sqlStr := "SELECT id, name, age FROM user WHERE id > ?" var users []user if err := db.Select(&users, sqlStr, 0); err != nil { fmt.Printf("get data failed, err:%v\n", err) return } for i := 0; i < len(users); i++ { fmt.Printf("id:%d, name:%s, age:%d\n", users[i].Id, users[i].Name, users[i].Age) } }
在sqlx
庫中,使用插入、更新、刪除操做是和原生sql
庫實現是一致的,都是採用Exec
函數來實現的:
// 插入數據 func insertRow() { sqlStr := "INSERT INTO user(name, age) VALUES(?, ?)" result, err := db.Exec(sqlStr, "Meng小羽", 22) if err != nil { fmt.Printf("exec failed, err:%v\n", err) return } insertID, err := result.LastInsertId() if err != nil { fmt.Printf("get insert id failed, err:%v\n", err) return } fmt.Printf("insert data success, id:%d\n", insertID) }
// 更新數據 func updateRow() { sqlStr := "UPDATE user SET age = ? WHERE id = ?" result, err := db.Exec(sqlStr, 22, 6) if err != nil { fmt.Printf("exec failed, err:%v\n", err) return } affectedRows, err := result.RowsAffected() if err != nil { fmt.Printf("get affected failed, err:%v\n", err) return } fmt.Printf("update data success, affected rows:%d\n", affectedRows) }
// 刪除一行 func deleteRow() { sqlStr := "DELETE FROM user WHERE id = ?" result, err := db.Exec(sqlStr, 4) if err != nil { fmt.Printf("exec failed, err:%v\n", err) return } affectedRows, err := result.RowsAffected() if err != nil { fmt.Printf("get affected failed, err:%v\n", err) return } fmt.Printf("delete data success, affected rows:%d\n", affectedRows) }
在庫中提供最經常使用的就是NamedQuery
和NamedExec
函數,一個是執行對查詢參數命名並綁定,另外一個則是對 CUD 操做的查詢參數名的綁定:
// 綁定查詢 func selectNamedQuery() { sqlStr := "SELECT id, name, age FROM user WHERE age = :age" rows, err := db.NamedQuery(sqlStr, map[string]interface{}{ "age": 22, }) if err != nil { fmt.Printf("named query failed failed, err:%v\n", err) return } defer rows.Close() for rows.Next() { var u user if err := rows.StructScan(&u); err != nil { fmt.Printf("struct sacn failed, err:%v\n", err) continue } fmt.Printf("%#v\n", u) } }
// 使用 named 方法插入數據 func insertNamedExec() { sqlStr := "INSERT INTO user(name, age) VALUES(:name, :age)" result, err := db.NamedExec(sqlStr, map[string]interface{}{ "name": "里斯", "age": 18, }) if err != nil { fmt.Printf("named exec failed, err:%v\n", err) return } insertId, err := result.LastInsertId() if err != nil { fmt.Printf("get last insert id failed, err:%v\n", err) return } fmt.Printf("insert data success, id:%d\n", insertId) }
使用Begin
函數、Rollback
函數及Commit
函數實現事務操做:
// 開啓事務 func (db *DB) Begin() (*Tx, error) // 回滾事務 func (tx *Tx) Rollback() error // 提交事務 func (tx *Tx) Commit() error
示例代碼:
// 事務操做 func updateTransaction() (err error) { tx, err := db.Begin() if err != nil { fmt.Printf("transaction begin failed, err:%v\n", err) return err } defer func() { if p := recover(); p != nil { _ = tx.Rollback() panic(p) } else if err != nil { fmt.Printf("transaction rollback") _ = tx.Rollback() } else { err = tx.Commit() fmt.Printf("transaction commit") return } }() sqlStr1 := "UPDATE user SET age = ? WHERE id = ? " reuslt1, err := tx.Exec(sqlStr1, 18, 1) if err != nil { fmt.Printf("sql exec failed, err:%v\n", err) return err } rows1, err := reuslt1.RowsAffected() if err != nil { fmt.Printf("affected rows is 0") return } sqlStr2 := "UPDATE user SET age = ? WHERE id = ? " reuslt2, err := tx.Exec(sqlStr2, 19, 5) if err != nil { fmt.Printf("sql exec failed, err:%v\n", err) return err } rows2, err := reuslt2.RowsAffected() if err != nil { fmt.Printf("affected rows is 0\n") return } if rows1 > 0 && rows2 > 0 { fmt.Printf("update data success\n") } return }
最後將此開源項目放在此處,你們要是感興趣能夠給這個開源項目一個 Star,感謝。