MIT6.5830 Lab0-Go tutorial实验记录(二)

MIT6.5830 Lab0-Go tutorial实验记录(二) – WhiteNight's Site

标签:Golang, 数据库

在将数据库的数据转换为图表前,我们需要先测试是否能正常访问数据库文件。

写者注

为什么要怎么做?因为这块 非常容易出问题。在handlers中需要我们连接至数据库,并将数据转换为图片呈现在前端的html页面上。
问题在于这里各种报错原因都有,而且在lab0原本的代码上进行调试非常折磨,断点经常要打上一堆。但是由于我是先做完实验,再写的实验报告,所以实验过程中有很多图没截下来。这里只能提供一个大致思路理解了。

实验步骤

新建go项目以测试链接

新建一个go项目,只需要有一个main.go即可。

MIT6.5830 Lab0-Go tutorial实验记录(二)_第1张图片

打开main.go。现在我们需要先试着访问数据库文件。

自己编写也可以,这里我选择用lab0中sqlite_ridership_db中的SQL来做测试。SQL语句很显眼,所以还是不难找的。

MIT6.5830 Lab0-Go tutorial实验记录(二)_第2张图片

先把SQL语句写好,其他的功能待会再补齐。

package main

import (
	_ "github.com/mattn/go-sqlite3"
)

func main() {

	query := `
		SELECT SUM(total_ons)
		FROM rail_ridership
		WHERE season = 'Fall 2017'
			AND time_period_id NOT IN ('time_period_10', 'time_period_11')
			AND line_id = ?
		GROUP BY time_period_id
		ORDER BY time_period_id;
	`

}

“github.com/mattn/go-sqlite3”这东西是一个数据库驱动的包,导入它之后就可以通过GO对sqlite数据库进行操作了。

db, err := sql.Open("sqlite3", "建议使用数据库文件的绝对路径")
if err != nil {
	log.Fatal(err)
}
defer db.Close()
//要养成打开数据库后关闭链接的习惯

此时你的main.go代码应该如下

package main

import (
	"database/sql"
	"fmt"
	"log"

	_ "github.com/mattn/go-sqlite3"
)

func main() {
	db, err := sql.Open("sqlite3", "c:/Users/LENOVO/Desktop/template/testgo/mbta.sqlite")
	if err != nil {
		log.Fatal(err)
	}
	defer db.Close()
	query := `
		SELECT SUM(total_ons)
		FROM rail_ridership
		WHERE season = 'Fall 2017'
			AND time_period_id NOT IN ('time_period_10', 'time_period_11')
			AND line_id = ?
		GROUP BY time_period_id
		ORDER BY time_period_id;
	`

}

接下来对db执行些操作才能知道到底有没有成功连接,我们先看看原本在lab0中这个SQL起什么作用。

MIT6.5830 Lab0-Go tutorial实验记录(二)_第3张图片

可以看到,在lab0中Query传入了两个参数。前者我我们要执行的SELECT查询SQL语句。后者则为一个string类型的字符串。

而这个lineId会作为参数传入SQL语句中的”AND line_id =? “中,相当于是”AND line_id=lineId“.

但我们测试总不能也直接用lineId,我们得自己指定lineId=xxxxx。不过这个lineId…没说明是什么,只知道它可能是xx线路的id。但是这个id到底是什么格式,没打注释。那只能翻翻代码看看是啥意思。我们先看看它的定义

MIT6.5830 Lab0-Go tutorial实验记录(二)_第4张图片

还是没说lineId是什么,但我们从这个函数大概能推断出:GetRidership( )接收string类型的 lineId,并返回一个int类型的切片和error。

我们在文件中搜索lineId试试。此时在ridersihp_db_test中我们找到了lineIds

MIT6.5830 Lab0-Go tutorial实验记录(二)_第5张图片

还是没说它是干什么的,但我们知道了lineId应该和这四种颜色有关。我们推测lineId应该就是xxx地铁线路所代表的颜色。

实验步骤

navicat打开数据库文件mbta.sqlite

为了验证lineId和颜色有关,我们查看一下数据库结构。这里使用navicat打开mbta.sqlite。

MIT6.5830 Lab0-Go tutorial实验记录(二)_第6张图片

看到有个lines,还有个rail_ridership,那么会不会lineId表示的是不同地铁线路所表示的颜色呢?但咱对波士顿也没什么了解,波士顿的地铁有几号线,不知道;xx号线用什么颜色表示,不知道。不过不知道也不重要,我们打开lines看看

MIT6.5830 Lab0-Go tutorial实验记录(二)_第7张图片

很明显了,line_id就应该表示的是xx号线,即“x号线的id”。

写者注

做这步只是为了更好的了解自己这次实验到底是在干什么,方便我们后面编写Handlers的具体函数。

实验步骤

补全测试代码

那我们直接假设要查询“red line”这条线路的乘客量。那么把lab0中代码复制过来,再把lineId改成“red”试试,能获取到数据就说明连接是成功的。

package main

import (
	"database/sql"
	"fmt"
	"log"

	_ "github.com/mattn/go-sqlite3"
)

func main() {
	db, err := sql.Open("sqlite3", "c:/Users/LENOVO/Desktop/template/testgo/mbta.sqlite")
	if err != nil {
		log.Fatal(err)
	}
	defer db.Close()
	query := `
		SELECT SUM(total_ons)
		FROM rail_ridership
		WHERE season = 'Fall 2017'
			AND time_period_id NOT IN ('time_period_10', 'time_period_11')
			AND line_id = ?
		GROUP BY time_period_id
		ORDER BY time_period_id;
	`
	rows, err := db.Query(query, "green")
	defer rows.Close() //别忘了关闭连接
	fmt.Print(rows)
}

在fmt.Print(rows)那打个断点,方便我们查看变量的情况。调试一下,得到变量信息

MIT6.5830 Lab0-Go tutorial实验记录(二)_第8张图片

error为nil,说明连接过程没出现报错。rows也不为nil,说明rows确实获取到了数据库的数据。

附录

报错原因

在Lab0“连接至数据库”前,你需要确保以下几点:

  • 你电脑有安装gcc,cmd输入gcc -v能显示版本信息。
    • 这是因为sqlite本身的源代码是c编写的。所以要和go一起用的话需要本地有c语言的编译环境。
  • mbta.sqlite有读写权限。
    • 由于mbta.sqlite这个文件是你自己下载下来的。如果你用的是linux,该文件很有可能默认没有读写权限,建议给mbta.sqlite所在的文件夹直接chmod加上权限。如果用的是windows,右键mbta.sqlite打开属性,你大概率会发现该文件提示已被锁定。解除锁定即可。
    • 对于windows,上面这个操作如果最后还是拿不到数据库的数据,cmd输入
      cacls c:/xxx/database /e /t /g everyone:F 。将数据库所在的文件夹设置为所有人可写。应该就能解决问题了。

在测试用的main.go调试的时候,起码err必须是nil。rows之类的得根据你自己编写的SQL语句来看,如果是按Lab0给的实验代码,最后rows不能是nil。如果rows是nil的话只能根据error的信息自己慢慢查报错原因了。

写者注

多打断点多调试,理解代码后在几个go文件里找可能会出错的地方打上断点。我自己光是连接数据库这块打断点+调试就花了一个下午。

你可能感兴趣的:(GO语言,golang,开发语言,后端)