type
Post
status
Published
date
Jul 4, 2020
slug
summary
sqlx 可以认为是Go语言内置database/sql的封装,在内置database/sql基础上提供了功能强大的扩展tags
Golang
category
技术分享
icon
password
介绍
简化操作,提高效率,
sqlx 可以认为是Go语言内置database/sql的封装,在内置database/sql基础上提供了功能强大的扩展安装
go get github.com/jmoiron/sqlx
基本使用
连接
- 和原生方式差别不大
- 使用
sqlx.Connect方法,相当于 Open+Ping 两个操作,获得一个数据库连接对象db
var db *sqlx.DB func initDB() (err error) { dsn := "user:password@tcp(127.0.0.1:3306)/sql_test?charset=utf8mb4&parseTime=True" // 也可以使用MustConnect连接不成功就panic db, err = sqlx.Connect("mysql", dsn) if err != nil { fmt.Printf("connect DB failed, err:%v\n", err) return } //设置最大连接数等 db.SetMaxOpenConns(20) db.SetMaxIdleConns(10) return }
查询
注意:该库使用反射拿到结构体user的值,因此user字段名需要大写
- 单行查询
- 使用db的
Get方法进行单行查询,参数是(查询结果保存目标对象,语句,参数...) - 对象参数需要传递指针
func queryRowDemo() { sqlStr := "select id, name, age from user where id=?" var u user err := db.Get(&u, sqlStr, 1) if err != nil { fmt.Printf("get failed, err:%v\n", err) return } fmt.Printf("id:%d name:%s age:%d\n", u.ID, u.Name, u.Age) }
- 多行查询
- 使用
Select方法多行查询 - 对象参数需要传递指针
func queryMultiRowDemo() { sqlStr := "select id, name, age from user where id > ?" var users []user //定义保存批量数据的user切片 err := db.Select(&users, sqlStr, 0) // if err != nil { fmt.Printf("query failed, err:%v\n", err) return } fmt.Printf("users:%#v\n", users) }
增删改
和原生方式基本相同
// 插入数据 func insertRowDemo() { sqlStr := "insert into user(name, age) values (?,?)" ret, err := db.Exec(sqlStr, "沙河小王子", 19) if err != nil { fmt.Printf("insert failed, err:%v\n", err) return } theID, err := ret.LastInsertId() // 新插入数据的id if err != nil { fmt.Printf("get lastinsert ID failed, err:%v\n", err) return } fmt.Printf("insert success, the id is %d.\n", theID) } // 更新数据 func updateRowDemo() { sqlStr := "update user set age=? where id = ?" ret, err := db.Exec(sqlStr, 39, 6) if err != nil { fmt.Printf("update failed, err:%v\n", err) return } n, err := ret.RowsAffected() // 操作影响的行数 if err != nil { fmt.Printf("get RowsAffected failed, err:%v\n", err) return } fmt.Printf("update success, affected rows:%d\n", n) } // 删除数据 func deleteRowDemo() { sqlStr := "delete from user where id = ?" ret, err := db.Exec(sqlStr, 6) if err != nil { fmt.Printf("delete failed, err:%v\n", err) return } n, err := ret.RowsAffected() // 操作影响的行数 if err != nil { fmt.Printf("get RowsAffected failed, err:%v\n", err) return } fmt.Printf("delete success, affected rows:%d\n", n) }
结果绑定
DB.NamedExec方法用来绑定SQL语句与结构体,或map中的同名字段func insertUserDemo()(err error){ sqlStr := "INSERT INTO user (name,age) VALUES (:name,:age)" _, err = db.NamedExec(sqlStr, map[string]interface{}{ "name": "李白", "age": 9000, }) return }
NamedQuery与DB.NamedExec类似,但支持查询。事务操作
db.Beginx() tx.Exec() func transactionDemo2()(err error) { tx, err := db.Beginx() // 开启事务 if err != nil { fmt.Printf("begin trans failed, err:%v\n", err) return err } defer func() { if p := recover(); p != nil { tx.Rollback() panic(p) // re-throw panic after Rollback } else if err != nil { fmt.Println("rollback") tx.Rollback() // err is non-nil; don't change it } else { err = tx.Commit() // err is nil; if Commit returns error update err fmt.Println("commit") } }() sqlStr1 := "Update user set age=20 where id=?" rs, err := tx.Exec(sqlStr1, 1) if err!= nil{ return err } n, err := rs.RowsAffected() if err != nil { return err } if n != 1 { return errors.New("exec sqlStr1 failed") } sqlStr2 := "Update user set age=50 where i=?" rs, err = tx.Exec(sqlStr2, 5) if err!=nil{ return err } n, err = rs.RowsAffected() if err != nil { return err } if n != 1 { return errors.New("exec sqlStr1 failed") } return err }