在开始学习本节介绍的知识之前,读者首先要做的就是对数据库进行设置。本书在第2章就曾经介绍过安装并设置Postgres的具体方法,因为本节还会继续用到Postgres数据库,所以如果你尚未安装或者设置好这个数据库,那么请根据第2章介绍的方法进行设置。
在启动并设置好数据库之后,我们还需要执行以下3个步骤:
- 创建数据库用户;
- 为用户创建数据库;
- 运行安装脚本,创建执行相关操作所需的表。
首先,我们可以通过在命令行执行以下命令来创建数据库用户:
createuser -P -d gwp
这一命令会创建出一个名为gwp
的Postgres数据库用户,其中-P
选项会让createuser
程序在执行时弹出一个提示符,只需要在提示符出现之后输入相应的字符串,就可以将其设置为gwp
用户的密码,而-d
选项则会赋予gwp
用户创建数据库所需的权限。
接着,我们需要为gwp
用户创建数据库。通过在命令行执行以下命令,我们就可以创建一个名为gwp
的数据库:
createdb gwp
注意,这个数据库的名字跟我们刚刚创建的数据库用户的名字是一样的,都是gwp
。虽然数据库用户也可以创建与自己名字不同的数据库,但这样做需要额外的权限设置,所以为了让事情尽可能简单,我们这里将使用默认的数据库命名方式,也就是,为数据库用户创建一个与之同名的数据库。
在拥有了数据库之后,我们还需要创建一个表,这个表也是接下来的内容中我们唯一需要使用的表。首先,我们需要创建一个名为setup.sql
的文件,并将代码清单6-5所示的内容键入该文件中。
代码清单6-5 用于创建表的脚本
create table posts (
id serial primary key,
content text,
author varchar(255)
);
接着,我们还需要在命令行执行以下命令:
psql -U gwp -f setup.sql -d gwp
这样的话,我们就把接下来要用到的数据库设置好了。注意,在每次执行后续展示的代码之前,你可能都需要重复执行一次这条命令,以便清理并设置数据库。
在创建并设置好数据库之后,现在是时候来连接这个数据库了。代码清单6-6展示了一个名为store.go
的文件,文件中的代码对Postgres执行了一系列操作,而接下来的小节将会逐一地分析这些操作的实现原理。
代码清单6-6 使用Go对Postgres执行CRUD操作
package main
import (
"database/sql"
"fmt"
_ "github.com/lib/pq"
)
type Post struct {
Id int
Content string
Author string
}
var Db *sql.DB
func init() {
var err error
Db, err = sql.Open("postgres", "user=gwp dbname=gwp password=gwp sslmode=disable") //①
if err != nil {
panic(err)
}
}
func Posts(limit int) (posts []Post, err error) {
rows, err := Db.Query("select id, content, author from posts limit $1",limit)
if err != nil {
return
}
for rows.Next() {
post := Post{}
err = rows.Scan(&post.Id, &post.Content, &post.Author)
if err != nil {
return
}
posts = append(posts, post)
}
rows.Close()
return
}
func GetPost(id int) (post Post, err error) { //②
post = Post{}
err = Db.QueryRow("select id, content, author from posts where id = $1", id)
.Scan(&post.Id, &post.Content, &post.Author)
return
}
func (post *Post) Create() (err error) { //③
statement := "insert into posts (content, author) values ($1, $2) returning id"
stmt, err := Db.Prepare(statement)
if err != nil {
return
}
defer stmt.Close()
err = stmt.QueryRow(post.Content, post.Author).Scan(&post.Id)
return
}
func (post *Post) Update() (err error) {
_, err = Db.Exec("update posts set content = $2, author = $3 where id = $1",
post.Id, post.Content, post.Author)//④
return
}
func (post *Post) Delete() (err error) {
_, err = Db.Exec("delete from posts where id = $1", post.Id)// ⑤
return
}
func main() {
post := Post{Content: "Hello World!", Author: "Sau Sheong"}//⑥
fmt.Println(post)
post.Create()
fmt.Println(post)//⑦
readPost, _ := GetPost(post.Id)
fmt.Println(readPost)//⑧
readPost.Content = "Bonjour Monde!"
readPost.Author = "Pierre"
readPost.Update()
posts, _ := Posts()
fmt.Println(posts)//⑨
readPost.Delete()
}
- 连接到数据库
- 获取单独一篇帖子
- 创建一篇新帖子
- 更新帖子
- 删除一篇帖子
- {0 Hello World! Sau Sheong}
- {1 Hello World! Sau Sheong}
- {1 Hello World! Sau Sheong}
- [{1 Bonjour Monde! Pierre}]