goblog學習四

0day 發表於 2021-03-23
Go

資料庫

標準庫 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 協議》,轉載必須註明作者和本文連結