goblog学习四

数据库

标准库 database/sql中已经封装好数据库操作的接口和规范,如连接池管理、数据绑定、事务处理等。但对具体数据库类型需要第三方驱动,如果mysql sqlite等。

加载

var db *sql.DB //声明数据库操作变量
func initDB(){} //初始化操作函数,连接池管理等
func main() {
initDB() //调用函数进行初始化
}

建表函数

func createTables() {
createArticlesSQL := `CREATE TABLE IF NOT EXISTS articles(
id bigint(20) PRIMARY KEY AUTO_INCREMENT NOT NULL,
title varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
body longtext COLLATE utf8mb4_unicode_ci ); `
_, err  := db.Exec(createArticlesSQL)
checkError(err) }

把建表的sql语句赋给createArticlesSQL变量,然后执行db.Exec()。放在main中执行,判断没有就新建。这张表三个字段:id 是bigint类型作为主键并自增,titel为varchar类型 设置collate,body为longtext类型。

sql.Result

db.Exec() 执行一个不带返回结果集的命令。类似用在inser、update、delete上。
func (db *DB) Exec(query string, args …interface{}) (Result, error)

Result定义:

type Result interface {
LastInsertId() (int64, error)    // 使用 INSERT 向数据插入记录,数据表有自增 id 时,该函数有返回值
RowsAffected() (int64, error)    // 表示影响的数据表行数 
}

保存数据到数据库

博文数据需要保存到数据库中,新增一个函数,然后在处理器中调用:

articlesStoreHandler中:

lastInsertID, err := saveArticleToDB(title, body)
    if lastInsertID > 0 {
        fmt.Fprint(w, "插入成功,ID 为"+strconv.FormatInt(lastInsertID, 10))
    } else {
        checkError(err)
        w.WriteHeader(http.StatusInternalServerError)
        fmt.Fprint(w,  "500 服务器内部错误")
    }

重点讲saveArticlesToDB函数:

func saveArticleToDB(title string, body string) (int64, error) {}

处理步骤是先进行db.Perpare(),取得一个 *sql.Stmt,defer stmt.Close(),再执行stmt.Exec(title,body)插入,返回一个sql.Result,如果插入成功的话,结果集有返回的自增 ID。这里一个插入,访问数据库2次。

显示文章

二个步骤:读取数据,渲染模版。
在handlerShow中,先获取请求URL的id:

vars := mux.Vars(r)
id := vars["id"]

把sql查询语句赋个query,调用db.QueryRow()

err := db.QueryRow(query, id).Scan(&article.ID, &article.Title, &article.Body)

QueryRow() 会返回一个 sql.Row struct,Scan()将查询结果赋值到Article结构的变量article中。
Scan() 发现没有返回数据的话,会返回 sql.ErrNoRows 类型的错误。

读取成功后,用template.ParseFiles()加载模版进行渲染。
show.gohtml:

<!DOCTYPE html>
<html lang="en">
<head>
<title>{{ .Title }} —— 我的技术博客</title>
<style type="text/css">.error {color: red;}</style>
</head>
<body>
    <p>ID{{ .ID }}</p>
    <p>标题: {{ .Title }}</p>
    <p>内容:{{ .Body }}</p>
</body>
</html>
本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!