这是我参与「第三届青训营 -后端场」笔记创作活动的的第3篇笔记
最近在做青训营抖音的项目,无论是用户、视频信息还是社交功能的实现以及token验证都需要用到数据库相关的内容,在此对go操作数据库做一个简单的记录,方便自己以后查看,当然大家有什么不同的意见或者建议,都可以联系我,我们互相学习。
1.下载驱动包
和java一样,在链接数据库之前我们都需要下载相应的驱动并且导入到环境中。 windows系统:安装git工具,在git工具中输入go get github.com/go-sql-driver/mysql 命令下载mysql驱动包,将此包下载到GOPATH中的pkg文件夹下,然后输入:go install github.com/Go-SQL-Driver/MySQL进行安装。
如上图:先输入下载驱动包的指令,然后再输入安装该驱动包的指令
之后就可以在你自己的GOPATH的pkg目录下看到相应的驱动包了
2:创建go文件进行数据库连接
我这里用的编译器是JetBrains公司开发的GoLand。
首先,创建一个.go结尾的文件并引入一下包
连接数据库的代码如下
//用户名:密码^@tcp(地址:3306)/数据库
db, err := sql.Open("mysql", "root:123456%^@tcp(127.0.0.1:3306)/t_user?charset=utf8")
if err!=nil {
fmt.Println(err)
return
}
其中sql.Open中参数的意义及位置如下所示,一般来说不需要改动
("驱动名称","数据库用户名:密码@tcp(127.0.0.1:3306)/数据库名?设置字符集指令")
要注意严格区分大小写
3.对数据进行增删改查操作
增删改
如果有学过Java数据库的话,下面比较好理解。对于一个sql语句,在GO/Java中都是一个字符串,而大多数的字符串都是拼接而成的。因此就会有两种情况
(1)整个sql语句是完整确认的,这样的sql语句,我们采用 result,err:=db.Exec(sql语句) 比较合适
(2)sql语句不是确定的,是要通过变量来拼接的,那么使用通配符? 这点与Java一致,则使用如下的函数:
stmt,err:=db.Prepare(带?的sql语句)
result,err:=stmt.Exec(按照顺序以逗号分隔?的值) (其实就是Java里面的PreparedStatement)
查询
这是数据库操作的难点:也是分为6中的两种情况,只不过将Exec()换成Query(),这样result就是查询到的结果,
之后便是遍历 for result.Next(){ } 想获取结果值,需要定义一个变量,然后按照顺序result.Scan(&V1,&v2,); 这样值就传给了V1,V2
最后,没有难度,但是重要也是极其容易忽视的问题,关闭资源
defer db.Close()
4.完整代码
package main
import (
"database/sql"
"fmt"
_ "github.com/Go-SQL-Driver/MySQL"
)
//对错误检查的封装
func check (err error){
if err != nil{
fmt.Println(err)
}
}
func main() {
//创建数据库连接
db , err := sql.Open("mysql","root:root@tcp(127.0.0.1:3306)/book?charset=utf8")
check(err)
//创建结构体,接收从数据库中拿到的数据,结构体中的变量要和表中的字段一一对应
type member struct {
scan_id int `db :"scan_id"`
scan_goods_id int `db:"scan_goods_id"`
scan_time int `db:"scan_time"`
scan_member_id int `db:"scan_member_id"`
}
//执行sql语句
rows,err :=db.Query("select * from scan")
check(err)
//遍历查询的结果集合
for rows.Next(){
var s member
//将从数据库中查询到的值对应到结构体中相应的变量中
err = rows.Scan(&s.scan_goods_id,&s.scan_id,&s.scan_member_id,&s.scan_time)
check(err)
fmt.Println(s)
}
//关闭连接
defer db.Close()
}