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) }
注意
准备工作之创建表
我们创建一个简单的用户表。
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 关于事物有三个方法
模拟转账:张三-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,如何进行增删改查,最后还讲了以下什么是事物,如何操作事物。
当然,这种是最原始的方法,过程有些繁琐,了解入门就好,后面还有更方便的方法。
原文链接:https://77isp.com/post/10277.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日
扫码二维码
获取最新动态