操作MySQL之sqlx库

1|0一、介绍和使用

  • 上一篇我们用了go-sql-driver/mysql库来操作mysql,还有一个更优秀的库sqlx,它也是对标准库database/sql具体的实现,并进行进一步封装和新增了一些方法

1|11. 安装和快速使用

go get github.com/jmoiron/sqlx package main import ( "fmt" _ "github.com/go-sql-driver/mysql" //执行一些初始化操作 "github.com/jmoiron/sqlx" ) func main() { //1 链接方式一 DB,err:=sqlx.Open("mysql","root:123@tcp(127.0.0.1:3306)/lqz?charset=utf8") if err != nil { fmt.Println("链接出错:",err) } defer DB.Close() err=DB.Ping() if err!=nil { fmt.Println("通信出错",err) } // 2 链接方式二 //DB:=sqlx.MustOpen("mysql","root:123@tcp(127.0.0.1:3306)/lqz?charset=utf8") //defer DB.Close() //err:=DB.Ping() //if err!=nil { // fmt.Println("通信出错",err) //} }

2|0二、基本增删查改

  • 之前go-sql-driver/mysql库的用法完全兼容

2|11. 增加数据

// 1 增加数据 sqlStr := "insert into music(name, year,sign_id) values (?,?,?)" ret, err := DB.Exec(sqlStr, "听爸爸的话", 2023,1) if err != nil { fmt.Println("插入出错",err) return } theID, err := ret.LastInsertId() // 新插入数据的id if err != nil { fmt.Println("获取插入的id错误:",err) return } fmt.Println("插入成功,id为:", theID)

2|22. 修改数据

// 2 修改数据 sqlStr := "update music set name= ? where id = ?" ret, err := DB.Exec(sqlStr, "长大后我就成了你", 4) if err != nil { fmt.Println("更新失败",err) return } n, err := ret.RowsAffected() if err != nil { fmt.Println("获取影响的行数失败:",err) return } fmt.Println("更新成功,影响行数为:",n)

2|33. 删除数据

// 3 删除数据 sqlStr := "delete from music where id = ?" ret, err := DB.Exec(sqlStr, 1) if err != nil { fmt.Println("删除出错:",err) return } n, err := ret.RowsAffected() // 操作影响的行数 if err != nil { fmt.Println("获取操作影响的行数出错:",err) return } fmt.Println("删除成功,影响的行数为:",n)

2|44. 查询数据

// 4 查询数据单条 var music struct { Id int Name string Year string SignId int } //QueryRow后一定要调用Scan方法,否则持有的数据库链接不会被释放 err = DB.QueryRow("select * from music where id=?", 2).Scan(&music.Id, &music.Name, &music.Year, &music.SignId) if err != nil { fmt.Println("查询出错:", err) } fmt.Println(music) // 5 查询多条 sqlStr := "select * from music where id > ?" rows, err := DB.Query(sqlStr, 1) if err != nil { fmt.Println("查询出错:", err) return } // 关闭rows释放持有的数据库链接 defer rows.Close() // 循环读取结果集中的数据 for rows.Next() { var m struct { Id int Name string Year string SignId int } err := rows.Scan(&m.Id, &m.Name, &m.Year, &m.SignId) if err != nil { fmt.Println("遍历出错", err) return } fmt.Println(m) }

3|0三、其他查询

3|11. Get和Select查询

type Music struct { Id int Name string Year string SignId int `db:"sign_id"` } var music Music err=DB.Get(&music,"select * from music where id=?", 2) if err != nil { fmt.Println("查询出错",err) } fmt.Println(music) // Select 查询 type Music struct { Id int Name string Year string SignId int `db:"sign_id"` } var music []Music err=DB.Select(&music,"select * from music where id > ?", 2) if err != nil { fmt.Println("查询出错",err) } fmt.Println(music)

4|0四、其他方法

4|11. sqlx的NamedExec

  • 传参可使用key-value的形式,不用原来一个问号?对应一个参数
    用来绑定SQL语句与结构体或map中的同名字段
sqlStr := "insert into music(name, year,sign_id) values (:name,:year,:sign_id)" _, err = DB.NamedExec(sqlStr, map[string]interface{}{ "name": "好汉歌", "year": 2024, "sign_id":1, })

4|22. sqlx的NamedQuery

  • 支持查询
// 使用map作为查询名 type Music struct { Id int Name string Year string SignId int `db:"sign_id"` } sqlStr := "SELECT * FROM music WHERE name=:name" // 使用map做命名查询 rows, _ := DB.NamedQuery(sqlStr, map[string]interface{}{"name": "好汉歌"}) defer rows.Close() for rows.Next(){ var m Music rows.StructScan(&m) fmt.Println(m) } // 使用结构体作为查询名 type Music struct { Id int Name string Year string SignId int `db:"sign_id"` } sqlStr := "SELECT * FROM music WHERE name=:name" // 使用结构体做命名查询 var music=Music{Name:"好汉歌"} rows, _ := DB.NamedQuery(sqlStr,music) defer rows.Close() for rows.Next(){ var m Music rows.StructScan(&m) fmt.Println(m) }

5|0五、事务操作

  • sqlx提供了db.Beginx()tx.Exec()方法进行事务操作
tx, err := DB.Beginx() // 开启事务 if err != nil { fmt.Printf("开启事务错误:%v\n", err) return } _,err=tx.Exec("insert into music(name, year,sign_id) values (?,?,?)", "听奶奶的话",2023,1) if err != nil { tx.Rollback() // 出错就回滚 fmt.Println("出错回滚") return } _,err=tx.Exec("insert into music(name, year,sign_id) values (?,?,?)", "听爷爷的话") if err != nil { tx.Rollback() // 出错就回滚 fmt.Println("出错回滚") return } tx.Commit()

6|0六、连接池

  • 只用 sqlx.Open() 函数创建连接池,此时只是初始化了连接池,并没有连接数据库,连接都是惰性的,只有调用 sqlx.DB 的方法时,此时才真正用到了连接,连接池才会去创建连接,连接池很重要,它直接影响着你的程序行为

  • 连接池的工作原理也非常简单,当调用 sqlx.DB 的方法时,会首先去向连接池请求要一个数据库连接,如果连接池有空闲的连接,则返回给方法中使用,否则连接池将创建一个新的连接给到方法中使用;一旦将数据库连接给到了方法中,连接就属于方法了。方法执行完毕后,要不把连接所属权还给连接池,要不传递给下一个需要数据库连接的方法中,最后都使用完将连接释放回到连接池中

db.SetMaxOpenConns(100) // 设置连接池最大连接数 db.SetMaxIdleConns(20) // 设置连接池最大空闲连接数

__EOF__

本文作者BigSun丶
本文链接https://www.cnblogs.com/Mcoming/p/18073549.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   BigSun丶  阅读(21)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
点击右上角即可分享
微信分享提示