sqlx是一个三方库,是基于内置database/sql的一个扩展包。它包含database/sql的已有接口。
安装sqlx
使用如下命令安装:
go get github.com/jmoiron/sqlx
handle类
sqlx最大可能去实现database/sql一样的功能。有4中主要handle类型:
- sqlx.DB - 相当于database/sql中的sql.DB,代表一个数据库。
- sqlx.Tx - 相当于database/sql中的sql.Tx,代表一个事务。
- sqlx.Stmt = 相当于database/sql中的sql.Stmt,代表一条要执行的预处理语句。
- sqlx.NamedStmt - 代表一条有参数的执行语句。
所有handle类型内嵌实现了对应database/sql中handle。也就是说,当你在代码中调用sqlx.DB.Query的时候,同时也会调用执行到sql.DB.Query对应的代码。
除此之外,还有两种指针类型:
- sqlx.Rows - 相当于sql.Rows, 从Queryx返回的指针;
- sqlx.Row - 相当于sql.Row, 从QueryRowx返回的结果;
跟handle类型一样,sqlx.Rows内嵌了sql.Rows。犹豫sql.Row的底层实现未公开,sqlx.Row只是实现了sql.Row的部分标准接口。
基本使用
连接数据库
由于sqlx是基于database/sql,所以其有两种连接方式。
(1)、使用Open函数,如下:
var db *sqlx.DB// 初始化数据库func initDB(dsn string) (err error) {db, err = sqlx.Open("mysql", dsn)if err != nil {return}err = db.Ping()if err != nil {return}db.SetMaxIdleConns(10)db.SetMaxOpenConns(10)return}
(2)、使用NewDb方法,如下:
var db *sqlx.DBfunc initDB(dsn string) (err error) {db = sqlx.NewDb(sql.Open("mysql", dsn), "mysql")err = db.Ping()if err != nil {return}db.SetMaxIdleConns(10)db.SetMaxOpenConns(10)return}
(3)、使用connect方法,如下:
var db *sqlx.DBfunc initDB(dsn string) (err error) {db, err = sqlx.Connect("mysql", dsn)if err != nil {return}db.SetMaxIdleConns(10)db.SetMaxOpenConns(10)return}
CRUD
查询
(1)、单行查询
func selectData(id int) {sqlStr := "select id,name,age from user where id = ?"var u usererr := db.Get(&u, sqlStr, id)if err != nil {fmt.Println("查询失败.err:", err)return}// 输出fmt.Printf("id:%d name:%s age:%d\n", u.ID, u.Name, u.Age)}
(2)、多行查询
// 多行查询func selectMutiData(id int) {sqlStr := "select id,name,age from user where id > ?"var u []usererr := db.Select(&u, sqlStr, id)if err != nil {fmt.Println("查询失败.err:", err)return}for _, v := range u {fmt.Printf("id:%d name:%s age:%d\n", v.ID, v.Name, v.Age)}}
插入、更新、删除
sqlx中的exec方法与原生sql中的exec使用基本一致:
// 插入数据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() // 新插入数据的idif 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)}
事务操作
对于事务操作,我们可以使用sqlx中提供的db.Beginx()和tx.MustExec()方法来简化错误处理过程。
示例代码如下:
func transactionDemo() {tx, err := db.Beginx() // 开启事务if err != nil {if tx != nil {tx.Rollback()}fmt.Printf("begin trans failed, err:%v\n", err)return}sqlStr1 := "Update user set age=40 where id=?"tx.MustExec(sqlStr1, 2)sqlStr2 := "Update user set age=50 where id=?"tx.MustExec(sqlStr2, 4)err = tx.Commit() // 提交事务if err != nil {tx.Rollback() // 回滚fmt.Printf("commit failed, err:%v\n", err)return}fmt.Println("exec trans success!")}
