在开始学习本节介绍的知识之前,读者首先要做的就是对数据库进行设置。本书在第2章就曾经介绍过安装并设置Postgres的具体方法,因为本节还会继续用到Postgres数据库,所以如果你尚未安装或者设置好这个数据库,那么请根据第2章介绍的方法进行设置。

在启动并设置好数据库之后,我们还需要执行以下3个步骤:

  1. 创建数据库用户;
  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()
}
  1. 连接到数据库
  2. 获取单独一篇帖子
  3. 创建一篇新帖子
  4. 更新帖子
  5. 删除一篇帖子
  6. {0 Hello World! Sau Sheong}
  7. {1 Hello World! Sau Sheong}
  8. {1 Hello World! Sau Sheong}
  9. [{1 Bonjour Monde! Pierre}]

results matching ""

    No results matching ""