2022-10-27 364
前言
上次咱们学习了如何使用Go操作Mysql,并且实现了简单的增删改查。
但是相对来说,还有有点复杂的,可能那些大佬也都觉得繁琐叭。
就又开发出了增强版查询Mysql操作库Sqlx。
mod文件
go.mod
modulesqlxDemo go1.14 require( github.com/go-sql-driver/mysqlv1.4.0 github.com/jmoiron/sqlxv1.2.0 google.golang.org/appenginev1.6.7//indirect )
创建数据表
创建表代码
CREATETABLE`userinfo`( `id`int(11)NOTNULLAUTO_INCREMENT, `name`varchar(10)DEFAULTNULL, `phone`char(11)DEFAULTNULL, `address`varchar(64)DEFAULTNULL, PRIMARYKEY(`id`) )ENGINE=InnoDBAUTO_INCREMENT=4DEFAULTCHARSET=utf8mb4;
创建结构体
结构体代码
typeUserinfostruct{ Idint64`json:"id"` Namestring`json:"name"` Phonestring`json:"phone"` Addressstring`json:"address"` }
连接数据库
代码
import( "fmt" _"github.com/go-sql-driver/mysql" "github.com/jmoiron/sqlx" ) typeUserinfostruct{ Idint64`json:"id"` Namestring`json:"name"` Phonestring`json:"phone"` Addressstring`json:"address"` } funcmain(){ dsn:="root:rootroot@tcp(127.0.0.1:3306)/go_mysql_demo?charset=utf8mb4&parseTime=True" //使用MustConnect连接的话,验证失败不成功直接panic //db:=sqlx.MustConnect("mysql",dsn) //使用Connect连接,会验证是否连接成功, db,err:=sqlx.Connect("mysql",dsn) iferr!=nil{ fmt.Printf("connectDBfailed,err:%v\n",err) return } db.SetMaxOpenConns(20) db.SetMaxIdleConns(10) }
查询单条
我记得使用原来的方式进行查询并且绑定结构体,是这审的。
//查询单条 sqlStr:="SELECTid,`name`,phone,addressfromuserinfowhereid=?;" varuserUserinfo err=db.QueryRow(sqlStr,1).Scan(&user.Id,&user.Name,&user.Phone,&user.Address) iferr!=nil{ fmt.Println("查询失败",err) return }
看第4行代码,需要将结构体的字段一个一个点上去。
如果使用sqlx呢?
代码
//查询 sqlStr:="SELECTid,`name`,phone,addressfromuserinfowhereid=?;" varuserUserinfo err=db.Get(&user,sqlStr,1) iferr!=nil{ fmt.Println("查询失败:",err) return } fmt.Println("user:",user)
执行结果
还是第4行代码,直接一个结构体扔过去,就绑定成功了。
如果表有很多字段,结构体字段也有很多,这个是很有用的。
查询多条
还是惯例,看看原来是怎么查的。
//查询多条 sqlStr:="SELECTid,`name`,phone,addressfromuserinfowhereid>=?" //参数同QueryRow rows,err:=db.Query(sqlStr,1) //处理err //此处使用rows释放所有链接 deferrows.Close() //循环整理所有数据 varuserList=make([]Userinfo,0,10) forrows.Next(){ varuserUserinfo err=rows.Scan(&user.Id,&user.Name,&user.Phone,&user.Address) //处理err userList=append(userList,user) } fmt.Println(userList)
为了方便,我去掉了err,使用伪代码处理err代替。
原来的方法,查询出来还得需要一个循环,还需要一个切片,乖乖嘞,打扰了。
来看看sqlx
代码
//查询多条 sqlStr:="SELECTid,`name`,phone,addressfromuserinfowhereid>=?" varuserList[]Userinfo err=db.Select(&userList,sqlStr,1) iferr!=nil{ fmt.Println("查询失败:",err) return } fmt.Println("userList:",userList)
执行结果
还是直接扔过去,就绑定完成了,真是美滋滋。
添加
额,添加,更新,删除,事物的话,似乎跟原来差不多,直接看代码叭。
代码
//添加 sqlStr:="INSERTintouserinfo(name,phone,address)values(?,?,?);" result,err:=db.Exec(sqlStr,"吴彦祖",555,"不知道哪的") iferr!=nil{ fmt.Println("插入失败",err) return } row_affect,err:=result.RowsAffected() iferr!=nil{ fmt.Println("受影响行数获取失败:",err) return } fmt.Println("受影响的行数:",row_affect) lastId,err:=result.LastInsertId() iferr!=nil{ fmt.Println("新增行id获取失败:",err) return } fmt.Println("新增行id:",lastId) fmt.Println("插入成功")
执行结果
Mysql
更新
代码
//更新数据 sqlStr:=`UPDATEuserinfosetname=?whereid=?;` result,err:=db.Exec(sqlStr,"吴彦祖666",4) iferr!=nil{ fmt.Println("更新失败",err) return } //受影响的行数 row_affect,err:=result.RowsAffected() iferr!=nil{ fmt.Println("受影响行数获取失败:",err) return } fmt.Println("受影响的行数:",row_affect) fmt.Println("更新成功")
执行结果
Mysql
删除
代码
sqlStr:="deletefromuserinfowhereid=?;" result,err:=db.Exec(sqlStr,4) iferr!=nil{ fmt.Println("删除失败",err) return } //受影响的行数 row_affect,err:=result.RowsAffected() iferr!=nil{ fmt.Println("受影响行数获取失败:",err) return } fmt.Println("受影响的行数:",row_affect) fmt.Println("删除成功")
执行结果
Mysql
事物
代码
//事物 tx,err:=db.Begin() iferr!=nil{ //释放事物 iftx!=nil{ tx.Rollback() } fmt.Println("事物开启失败") return } 张三减10块Sql:=`UPDATEbillsetmoney=money-10wherename=?;` result,err:=tx.Exec(张三减10块Sql,"张三") iferr!=nil{ //有错误表示更是失败,回滚原来状态 tx.Rollback() fmt.Println(err) return } 张三受影响行数,err:=result.RowsAffected() iferr!=nil{ tx.Rollback()//回滚 return } 李四加10块Sql:=`UPDATEbillsetmoney=money+10wherename=?;` result,err=tx.Exec(李四加10块Sql,"李四") iferr!=nil{ //有错误表示更是失败,回滚原来状态 tx.Rollback() fmt.Println(err) return } 李四受影响行数,err:=result.RowsAffected() iferr!=nil{ tx.Rollback()//回滚 return } //都等于1表示成功,可以提交事务,修改数据 if张三受影响行数==1&&李四受影响行数==1{ //提交事务 fmt.Println("提交事务") tx.Commit() }else{ //有一个!=1表示没有更新成功,可能用户不存在 fmt.Println("失败了,事物回滚了") tx.Rollback() } fmt.Println("事物执行成功")
执行结果
Mysql
NameExec
做增 删 改使用。
NameExec方法是通过结构体或Map绑定SQL语句,试了试,感觉用处不大,不做举例。
NameQuery
做查询使用。
用法同上,没用,不做举例。
总结
其实sqlx模块,最大的改进是在查询方面,相信你也看到了,确实会比原生查询方便很多很多。
但是在其他方便,就显得捉襟见肘了,但是又说,一般还是查询场景多,查多改少。
原文链接:https://77isp.com/post/10283.html
=========================================
https://77isp.com/ 为 “云服务器技术网” 唯一官方服务平台,请勿相信其他任何渠道。
数据库技术 2022-03-28
网站技术 2022-11-26
网站技术 2023-01-07
网站技术 2022-11-17
Windows相关 2022-02-23
网站技术 2023-01-14
Windows相关 2022-02-16
Windows相关 2022-02-16
Linux相关 2022-02-27
数据库技术 2022-02-20
抠敌 2023年10月23日
嚼餐 2023年10月23日
男忌 2023年10月22日
瓮仆 2023年10月22日
簿偌 2023年10月22日
扫码二维码
获取最新动态