姓名:王迎旭
学号:16340226
分工:后端
主要负责:handler函数的完善 以及 在本地的测试
这次项目自己完成了部分后端代码的补充工作,基于 天扬dalao 已经搭好的框架 和 泽浩dalao 已经给出的示例,自己继续再进行操作工作就变得简单很多了,比如:
基于函数peopleIdHandler()
,完成后面vehicle
、starship
、planet
、flims
等操作
func peopleIdHandler(formatter *render.Render,db *bolt.DB) http.HandlerFunc{
return func(w http.ResponseWriter, req *http.Request){
vars := mux.Vars(req)
// 获取id
id := vars["id"]
// 从db中获得Person Struct
v, err := dbOperator.GetElementById(db, "Person", id)
if err != nil {
fmt.Println(err)
// WriteResponse(w, ErrorResponseCode, "failed", nil)
formatter.Text(w, http.StatusOK, "HTTP/1.0 "+ErrorResponseCode+" Not Found\n")
} else {
var user swapi.Person
err = json.Unmarshal(v, &user)
if err != nil {
fmt.Println(err)
} else {
formatter.Text(w, http.StatusOK, "HTTP/1.0 "+SuccessResponseCode+" OK\n")
formatter.Text(w, http.StatusOK, "Content-Type: application/json\n")
formatter.JSON(w,http.StatusOK,user)
}
}
}
}
这部分的工作就是我们可以实现,在捕获到请求之后,返回对应的 某物对应ID
的json
信息,如果找到就可以成功显示并给出提示信息,如果不能,就显示报错:
如输入指令http://localhost:3000/api
,访问 root
:
HTTP/1.0 200 OK
Content-Type: application/json
{
"films": "http://localhost:3000/api/films/",
"people": "http://localhost:3000/api/people/",
"planets": "http://localhost:3000/api/planets/",
"species": "http://localhost:3000/api/species/",
"starships": "http://localhost:3000/api/starships/",
"vehicles": "http://localhost:3000/api/vehicles/"
}
在完成函数的书写之后,在本地的测试也遇到了一点问题:
git bash
显示网页已经成功响应,但是并不能在主界面上显示对应的信息针对上面的问题,自己也是尝试进行了解决:
push
到github
上的代码clone
到本地的/gowork/src/github.com/
路径下,从新进行编译,这次再次输入访问指令,git bash
成功响应,chrome
成功返回对应信息;不过还不是很清楚,为什么在桌面上放置的安装包,成功编译之后无法在chrome
上显示/gowork/src/github.com/
路径下慢慢安装了,不过建议以后import
时候,注意小组成员之间统一路径写法kill
掉占用 8080 端口的进程大二下学年学习过 postgresql
如何使用,但是并没有真正的跟实际的编程联系起来,这次接着完成项目的机会,自己也是对boltdb
进行了一点了解,首先是boltdb
非常适合于Go
项目编程对数据库操作的需要,同时非常适合我这样的小白初次接触使用。
Go
库中安装 boltdb
go get github.com/boltdb/bolt
db, err := bolt.Open("my.db", 0600, nil)
这里的Open
的参数,与 c++
的参数设置比较像,第一个为数据库的路径,如果不存在则创建新的数据库,第二个参数为文件操作,第三个参数为可选参数;
err := db.Update(func(tx *bolt.Tx) error {
...
return nil
})
err的返回值报告导致您的事务不能完成的所有磁盘故障
每一次新的事物都需要等待上一次事物的结束,这种开销我们可以通过DB.Batch()
批处理来完成
err := db.Batch(func(tx *bolt.Tx) error {
...
return nil
})
在批处理过程中如果某个事务失败了,批处理会多次调用这个函数函数返回成功则成功。如果中途失败了,则整个事务会回滚。
DB.Begin()
启动函数包含在db.update
和db.batch
中,该函数启动事务开始执行事务并返回结果关闭事务.
// Start a writable transaction.
tx, err := db.Begin(true)
if err != nil {
return err
}
defer tx.Rollback()
// Use the transaction...
_, err := tx.CreateBucket([]byte("MyBucket"))
if err != nil {
return err
}
// Commit the transaction and check for error.
if err := tx.Commit(); err != nil {
return err
}
数据结构
桶桶是数据库中键/值对的集合。桶中的所有键必须是唯一的。可以使用DB.CreateBucket()
创建一个桶:
db.Update(func(tx *bolt.Tx) error {
b, err := tx.CreateBucket([]byte("MyBucket"))
if err != nil {
return fmt.Errorf("create bucket: %s", err)
}
return nil
})
也可以使用Tx.CreateBucketIfNotExists()
来创建桶,该函数会先判断是否已经存在该桶不存在即创建, 删除桶可以使用Tx.DeleteBucket()
来完成
k-v
对存储键值对到桶里可以使用Bucket.Put()
来完成:
db.Update(func(tx *bolt.Tx) error {
b := tx.Bucket([]byte("MyFriendsBucket"))
err := b.Put([]byte("one"), []byte("zhangsan"))
return err
})
获取键值Bucket.Get()
:
db.View(func(tx *bolt.Tx) error {
b := tx.Bucket([]byte("MyFriendsBucket"))
v := b.Get([]byte("one"))
fmt.Printf("The answer is: %s\n", v)
return nil
})
get()
函数不返回一个错误,因为它的运行是保证工作(除非有某种系统故障)。如果键存在,那么它将返回它的值。如果它不存在,那么它将返回nil。
还需要注意的是当事务打开都get返回的值时唯一有效的,如果需要将该值用于其他事务,可以通过copy
拷贝到其他的byte slice
中
如果你知道所在桶中拥有键,你也可以使用ForEach()来迭代:
db.View(func(tx *bolt.Tx) error {
// Assume bucket exists and has keys
b := tx.Bucket([]byte("MyBucket"))
b.ForEach(func(k, v []byte) error {
fmt.Printf("key=%s, value=%s\n", k, v)
return nil
})
return nil
})