Go语言操作MySQL语言基础知识

 2022-10-27    346  

前言

通常情况下,我们程序员和数据库打交道是最多的。要然我们怎么会被称为码农呢。

存用户信息需要数据库,存订单需要数据库,等等等等,现在真是数据驱动着发展。

但是数据库种类有很多,有Mysql,Oracle,SQL Server。

本篇就示例如何Go操作Mysql。

准备工作

本次使用的是go mod进行包依赖管理,还不会使用的向上爬梯子,找go mod用法。

使用的库是第三方库go-sql-driver/mysql。

准备工作之连接数据库

代码

funcmain(){
varusername="root"
varpassword="rootroot"
varip="127.0.0.1"
varport="3306"
vardata="go_mysql_demo"
vardsn=fmt.Sprintf("%s:%s@tcp(%s:%s)/%s",username,password,ip,port,data)
//Open只会验证dsb的格式是否正确,不会验证是否连接成功,同理,密码是否正确也不知道
db,err:=sql.Open("mysql",dsn)
iferr!=nil{
panic(err)
}
//关闭连接在err之后,因为可能直接就打开不成功,关闭一个没有打开的连接???
deferdb.Close()
//此时尝试连接数据库,会判断用户,密码,ip地址,端口是否正确
err=db.Ping()
iferr!=nil{
fmt.Println("连接数据库失败,",err)
return
}
//设置与数据库建立连接的最大数目,一般不管
db.SetMaxOpenConns(100)
//设置连接池中的最大闲置连接数,一般不管
db.SetMaxIdleConns(50)
}

注意

  • sql.Open只会验证格式是否正确,不会连接数据库。
  • db.Close在err之后,是因为可能打开不成功,关闭一个没有打开的连接。
  • db.Ping会连接数据库,判断用户,密码,ip地址,端口是否正确。

准备工作之创建表

我们创建一个简单的用户表。

CREATETABLE`userinfo`(
`id`int(11)NOTNULLAUTO_INCREMENT,
`name`varchar(10)DEFAULTNULL,
`phone`char(11)DEFAULTNULL,
`address`varchar(64)DEFAULTNULL,
PRIMARYKEY(`id`)
)ENGINE=InnoDBDEFAULTCHARSET=utf8mb4;

准备工作之创建结构体

假设上述工作都完成了啊。

不知道有没有想过,我们查询的数据,存成啥?,字符串?map?切片?,似乎都不是太好。

只有结构体是最清晰的,最好认识的。

结构体

typeUserinfostruct{
Idint64`json:"id"`
Namestring`json:"name"`
Phonestring`json:"phone"`
Addressstring`json:"address"`
}

查询单条

单条查询使用QueryRow方法。

代码

//查询单条
sqlStr:="SELECTid,`name`,phone,addressfromuserinfowhereid=?;"
varuserUserinfo
/*
QueryRow第二个参数可以接收多个参数,同理,sqlStr可以有多个?占位符进行匹配
QueryRow之后必须调用Scan方法进行数据绑定,进行数据库链接释放
*/
err=db.QueryRow(sqlStr,1).Scan(&user.Id,&user.Name,&user.Phone,&user.Address)
iferr!=nil{
fmt.Println("查询失败",err)
return
}
fmt.Println(user)

执行结果

查询多条

多行查询使用Query。

代码

//查询多条
sqlStr:="SELECTid,`name`,phone,addressfromuserinfowhereid>=?"
//参数同QueryRow
rows,err:=db.Query(sqlStr,1)
iferr!=nil{
fmt.Println("查询失败:",err)
return
}
//此处使用rows释放所有链接
deferrows.Close()
//循环整理所有数据
varuserList=make([]Userinfo,0,10)
forrows.Next(){
varuserUserinfo
err=rows.Scan(&user.Id,&user.Name,&user.Phone,&user.Address)
iferr!=nil{
fmt.Println("绑定数据失败",err)
return
}
userList=append(userList,user)
}
fmt.Println(userList)

执行结果

插入数据

插入数据需要用到Exec。

代码

//插入数据
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

更新数据

更新和添加差不多,用的都是Exec。

代码

//更新数据
sqlStr:=`UPDATEuserinfosetname=?whereid=?;`
result,err:=db.Exec(sqlStr,"吴彦祖666",3)
iferr!=nil{
fmt.Println("更新失败",err)
return
}
//受影响的行数
row_affect,err:=result.RowsAffected()
iferr!=nil{
fmt.Println("受影响行数获取失败:",err)
return
}
fmt.Println("受影响的行数:",row_affect)
fmt.Println("更新成功")

执行结果

Mysql

删除数据

删除数据用的还是Exec。

代码

//删除数据
sqlStr:="deletefromuserinfowhereid=?;"
result,err:=db.Exec(sqlStr,3)
iferr!=nil{
fmt.Println("删除失败",err)
return
}
//受影响的行数
row_affect,err:=result.RowsAffected()
iferr!=nil{
fmt.Println("受影响行数获取失败:",err)
return
}
fmt.Println("受影响的行数:",row_affect)
fmt.Println("删除成功")

执行结果

Mysql

事物

事物,这个用的就比较多了,通常用在关键的场景。

尤其是转账,张三-10块,李四+10块,这个动作动作是要在一起完成的。

如果任何一个失败了,就要恢复上一次的状态。

我们通常也叫这个操作叫做原子操作,要成功,都成功,要完蛋,都完蛋。

新建表

CREATETABLE`bill`(
`id`int(11)NOTNULLAUTO_INCREMENT,
`name`varchar(8)NOTNULL,
`money`int(11)NOTNULL,
PRIMARYKEY(`id`)
)ENGINE=InnoDBAUTO_INCREMENT=3DEFAULTCHARSET=utf8mb4;

表数据

张三和李四都剩余100块

Go Mysql 关于事物相关方法

Go 关于事物有三个方法

  • Begin()开始事物。
  • Commit()提交事物。
  • Rollback()失败回滚。

模拟转账:张三-10块,李四+十块

代码

funcmain(){
//事物
//开启事物
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

一加一减

假如出错了

Mysql

如果使用事物,出错了数据还是没变。

总结

本次主要讲述了Go如何操作Mysql,如何进行增删改查,最后还讲了以下什么是事物,如何操作事物。

当然,这种是最原始的方法,过程有些繁琐,了解入门就好,后面还有更方便的方法。

  •  标签:  
  • MySQL
  •  

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

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

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