当前位置: 首页 > 科技观察

Go语言增强版操作MySQL(SQLX)

时间:2023-03-13 07:34:33 科技观察

前言上次我们学习了如何使用Go操作Mysql,实现了简单的增删改查。不过相对来说还是有些复杂,说不定那些大佬也觉得麻烦。开发了增强版的查询Mysql操作库Sqlx。mod文件go.modmodulesqlxDemogo1.14require(github.com/go-sql-driver/mysqlv1.4.0github.com/jmoiron/sqlxv1.2.0google.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连接,验证Failure不成功直接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)}查询单个item我记得用原来的方法查询绑定结构,这个是试用//query单个项目sqlStr:="SELECTid,`name`,phone,addressfromuserinfowhereid=?;"varuserUserinfoerr=db.QueryRow(sqlStr,1).Scan(&user.Id,&user.Name,&user.Phone,&user.Address)iferr!=nil{fmt.Println("Queryfailed",err)return}看第4行代码,需要一个一个点击结构体的字段。如果使用sqlx呢?代码//querysqlStr:="SELECTid,`name`,phone,addressfromuserinfowhereid=?;"varuserUserinfoerr=db.Get(&user,sqlStr,1)iferr!=nil{fmt.Println("queryfailed:",err)return}fmt.Println("user:",user)执行结果还是第4行代码,直接抛出一个结构体,绑定成功。如果表有很多字段,并且结构字段也有很多字段,这很有用。查询多个项目并查看它最初是如何检查的仍然是常见的做法。//查询多个sqlStr:="SELECTid,`name`,phone,addressfromuserinfowhereid>=?"//参数同QueryRowrows,err:=db.Query(sqlStr,1)//处理err//使用行在这里释放所有链接deferrows.Close()//遍历所有数据varuserList=make([]Userinfo,0,10)forrows.Next(){varuserUserinfoerr=rows.Scan(&user.Id,&user.Name,&user.Phone,&user.Address)//处理erruserList=append(userList,user)}fmt.Println(userList)为了方便,我去掉了err,改用伪代码来处理err。在原来的方法中,需要一个循环和一个切片来找出查询,所以请原谅。看看sqlx代码//查询多个sqlStr:="SELECTid,`name`,phone,addressfromuserinfowhereid>=?"varuserList[]Userinfoerr=db.Select(&userList,sqlStr,1)iferr!=nil{fmt.Println("Queryfailed:",err)return}fmt.Println("userList:",userList)执行结果还是直接抛出,绑定完成,真是不敢恭维。添加,添加,更新,删除,东西,好像和原来差不多,看代码就好了。代码//添加sqlStr:="INSERTintouserinfo(name,phone,address)values(?,?,?);"result,err:=db.Exec(sqlStr,"吴彦祖",555,"我不知道where")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("newrowid:",lastId)fmt.Println("插入成功")执行结果Mysql更新代码//更新数据sqlStr:=`UPDATEuserinfosetname=?whereid=?;`result,err:=分贝。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("更新成功")执行结果MysqldeletecodesqlStr:="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("Thingfailedtoopen")return}张三减10Sql:=`UPDATEbillsetmoney=money-10wherename=?;`result,err:=tx.Exec(张三减10Sql,"ZhangSan")iferr!=nil{//如果有错误,则表示失败,回滚原状态tx.Rollback()fmt.Println(err)return}张三影响的行数,err:=result.RowsAffected()iferr!=nil{tx.Rollback()//回滚返回}李思嘉10Sql:=`UPDATEbillsetmoney=money+10wherename=?;`result,err=tx.Exec(李思嘉10Sql,"李四")iferr!=nil{//出错表示失败,回滚原状态tx.Rollback()fmt.Println(err)return}李四影响的行数,err:=result.RowsAffected()iferr!=nil{tx.Rollback()//回滚返回}//全部等于1表示成功,可以提交事务,修改数据如果张三影响的行数==1&&李四影响的行数==1{//提交事务fmt.Println("提交事务")tx.Commit()}else{//有a!=1表示更新不成功,用户可能不存在t;)MysqlNameExec增删改查的执行结果,使用NameExec方法通过结构体或Map绑定SQL语句,试过了,但用处不大,就不举例了。NameQuery用于查询。用法同上,无用,不举例。总结一下,其实sqlx模块最大的改进是在查询上。我相信你也看到了。确实比原来的查询方便多了。但是在其他方便的地方,好像是捉襟见肘,不过也说一般情况下要查的场景多,查的多改的少。