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

 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模块,最大的改进是在查询方面,相信你也看到了,确实会比原生查询方便很多很多。

但是在其他方便,就显得捉襟见肘了,但是又说,一般还是查询场景多,查多改少。

  •  标签:  
  • MySQL
  •  

原文链接:https://77isp.com/post/10283.html

=========================================

https://77isp.com/ 为 “云服务器技术网” 唯一官方服务平台,请勿相信其他任何渠道。