Go语言链接数据库的两种方式之sql直连| 青训营笔记

253 阅读3分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的的第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进行安装。

image.png

如上图:先输入下载驱动包的指令,然后再输入安装该驱动包的指令
之后就可以在你自己的GOPATH的pkg目录下看到相应的驱动包了

2:创建go文件进行数据库连接

我这里用的编译器是JetBrains公司开发的GoLand。
首先,创建一个.go结尾的文件并引入一下包

image.png 连接数据库的代码如下

//用户名:密码^@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()
}