sqlx是一个三方库,是基于内置database/sql的一个扩展包。它包含database/sql的已有接口。

安装sqlx

使用如下命令安装:

  1. 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函数,如下:

  1. var db *sqlx.DB
  2. // 初始化数据库
  3. func initDB(dsn string) (err error) {
  4. db, err = sqlx.Open("mysql", dsn)
  5. if err != nil {
  6. return
  7. }
  8. err = db.Ping()
  9. if err != nil {
  10. return
  11. }
  12. db.SetMaxIdleConns(10)
  13. db.SetMaxOpenConns(10)
  14. return
  15. }

(2)、使用NewDb方法,如下:

  1. var db *sqlx.DB
  2. func initDB(dsn string) (err error) {
  3. db = sqlx.NewDb(sql.Open("mysql", dsn), "mysql")
  4. err = db.Ping()
  5. if err != nil {
  6. return
  7. }
  8. db.SetMaxIdleConns(10)
  9. db.SetMaxOpenConns(10)
  10. return
  11. }

(3)、使用connect方法,如下:

  1. var db *sqlx.DB
  2. func initDB(dsn string) (err error) {
  3. db, err = sqlx.Connect("mysql", dsn)
  4. if err != nil {
  5. return
  6. }
  7. db.SetMaxIdleConns(10)
  8. db.SetMaxOpenConns(10)
  9. return
  10. }

CRUD

查询

(1)、单行查询

  1. func selectData(id int) {
  2. sqlStr := "select id,name,age from user where id = ?"
  3. var u user
  4. err := db.Get(&u, sqlStr, id)
  5. if err != nil {
  6. fmt.Println("查询失败.err:", err)
  7. return
  8. }
  9. // 输出
  10. fmt.Printf("id:%d name:%s age:%d\n", u.ID, u.Name, u.Age)
  11. }

(2)、多行查询

  1. // 多行查询
  2. func selectMutiData(id int) {
  3. sqlStr := "select id,name,age from user where id > ?"
  4. var u []user
  5. err := db.Select(&u, sqlStr, id)
  6. if err != nil {
  7. fmt.Println("查询失败.err:", err)
  8. return
  9. }
  10. for _, v := range u {
  11. fmt.Printf("id:%d name:%s age:%d\n", v.ID, v.Name, v.Age)
  12. }
  13. }

插入、更新、删除

sqlx中的exec方法与原生sql中的exec使用基本一致:

  1. // 插入数据
  2. func insertRowDemo() {
  3. sqlStr := "insert into user(name, age) values (?,?)"
  4. ret, err := db.Exec(sqlStr, "沙河小王子", 19)
  5. if err != nil {
  6. fmt.Printf("insert failed, err:%v\n", err)
  7. return
  8. }
  9. theID, err := ret.LastInsertId() // 新插入数据的id
  10. if err != nil {
  11. fmt.Printf("get lastinsert ID failed, err:%v\n", err)
  12. return
  13. }
  14. fmt.Printf("insert success, the id is %d.\n", theID)
  15. }
  16. // 更新数据
  17. func updateRowDemo() {
  18. sqlStr := "update user set age=? where id = ?"
  19. ret, err := db.Exec(sqlStr, 39, 6)
  20. if err != nil {
  21. fmt.Printf("update failed, err:%v\n", err)
  22. return
  23. }
  24. n, err := ret.RowsAffected() // 操作影响的行数
  25. if err != nil {
  26. fmt.Printf("get RowsAffected failed, err:%v\n", err)
  27. return
  28. }
  29. fmt.Printf("update success, affected rows:%d\n", n)
  30. }
  31. // 删除数据
  32. func deleteRowDemo() {
  33. sqlStr := "delete from user where id = ?"
  34. ret, err := db.Exec(sqlStr, 6)
  35. if err != nil {
  36. fmt.Printf("delete failed, err:%v\n", err)
  37. return
  38. }
  39. n, err := ret.RowsAffected() // 操作影响的行数
  40. if err != nil {
  41. fmt.Printf("get RowsAffected failed, err:%v\n", err)
  42. return
  43. }
  44. fmt.Printf("delete success, affected rows:%d\n", n)
  45. }

事务操作

对于事务操作,我们可以使用sqlx中提供的db.Beginx()tx.MustExec()方法来简化错误处理过程。

示例代码如下:

  1. func transactionDemo() {
  2. tx, err := db.Beginx() // 开启事务
  3. if err != nil {
  4. if tx != nil {
  5. tx.Rollback()
  6. }
  7. fmt.Printf("begin trans failed, err:%v\n", err)
  8. return
  9. }
  10. sqlStr1 := "Update user set age=40 where id=?"
  11. tx.MustExec(sqlStr1, 2)
  12. sqlStr2 := "Update user set age=50 where id=?"
  13. tx.MustExec(sqlStr2, 4)
  14. err = tx.Commit() // 提交事务
  15. if err != nil {
  16. tx.Rollback() // 回滚
  17. fmt.Printf("commit failed, err:%v\n", err)
  18. return
  19. }
  20. fmt.Println("exec trans success!")
  21. }