Go 语言操作 MySQL 之 SQLX 包
SQLX 库 sqlx是 Go 的软件包,它在出色的内置database/sql软件包的基础上提供了一组扩展。 该库兼容 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 返回。 安装 SQLX 库 1 go get github.com/jmoiron/sqlx 使用操作 连接数据库 1 2 3 4 5 6 7 8 9 10 11 12 // 初始化数据库 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 的驱动包,如下设计: 1 2 3 4 5 6 7 8 9 10 11 12 13 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 函数实现: 1 func (db *DB) Get(dest interface{}, query string, args ...interface{}) error dest 是用户声明变量接收查询结果,query 为查询 SQL 语句,args 为绑定参数的赋值。 1 2 3 4 5 6 7 8 9 10 11 // 查询一行数据 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 函数: 1 func (db *DB) Select(dest interface{}, query string, args ...interface{}) error 使用 Select 函数进行查询的时候,需要先声明一个结构体数组接收映射过来的数据: 1 2 3 4 5 6 7 8 9 10 11 12 13 // 查询多行数据 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 函数来实现的: 插入操作 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 // 插入数据 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) } 更新操作 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 // 更新数据 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) } 删除操作 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 // 删除一行 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 操作的查询参数名的绑定: NamedQuery 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 // 绑定查询 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) } } NamedExec 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 // 使用 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函数实现事务操作: 1 2 3 4 5 6 // 开启事务 func (db *DB) Begin() (*Tx, error) // 回滚事务 func (tx *Tx) Rollback() error // 提交事务 func (tx *Tx) Commit() error 示例代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 // 事务操作 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 } }()
以上内容来自博客订阅源,版权归原作者。关注作者后可以在 关注列表 第一时间查看作者文章。
登录后,加入这场讨论。
登录参与