友情提示:此篇文章大约须要阅读 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,感谢。