操作數據庫
- 1 文章列表
- 2 刪除文章
1 文章列表
(1)先保證文章已經有多篇,可以直接在數據庫中添加,或者訪問鏈接: localhost:3000/articles/create,增加幾篇文章。
(2)之前設置好了articles.index 路由,訪問 localhost:3000/articles 顯示文章列表
(3)完善articlesIndexHandler()使之能夠顯示數據庫中的數據
.
.
.
func articlesIndexHandler(w http.ResponseWriter, r *http.Request) {// 1. 執行查詢語句,返回一個結果集rows, err := db.Query("SELECT * from articles")checkError(err)defer rows.Close()var articles []Article//2. 循環讀取結果for rows.Next() {var article Article// 2.1 掃描每一行的結果并賦值到一個 article 對象中err := rows.Scan(&article.ID, &article.Title, &article.Body)checkError(err)// 2.2 將 article 追加到 articles 的這個數組中articles = append(articles, article)}// 2.3 檢測遍歷時是否發生錯誤err = rows.Err()checkError(err)// 3. 加載模板tmpl, err := template.ParseFiles("resources/views/articles/index.gohtml")checkError(err)// 4. 渲染模板,將所有文章的數據傳輸進去err = tmpl.Execute(w, articles)checkError(err)
}
.
.
.
添加模板
resources/views/articles/index.gohtml
<!DOCTYPE html>
<html lang="en">
<head><title>所有文章 —— 我的技術博客</title><style type="text/css">.error {color: red;}</style>
</head>
<body><h1>所有文章</h1><ul>{{ range $key, $article := . }}<li><a href=""><strong>{{ $article.ID }}</strong>: {{ $article.Title }}</a></li>{{ end }}</ul>
</body>
</html>
訪問 localhost:3000/articles
為列表里的文章加上鏈接
.
.
'
// Article 對應一條文章數據
type Article struct {...
}// Link 方法用來生成文章鏈接
func (a Article) Link() string {showURL, err := router.Get("articles.show").URL("id", strconv.FormatInt(a.ID, 10))if err != nil {checkError(err)return ""}return showURL.String()
}
.
.
.
保存后刷新頁面并查看頁面源碼:
2 刪除文章
先開發后臺的刪除邏輯,然后在文章詳情頁里顯示刪除按鈕
(1)注冊articles.delete 路由
(2)添加articlesDeleteHandler()函數
.
.
.
func articlesDeleteHandler(w http.ResponseWriter, r *http.Request) {// 1. 獲取 URL 參數id := getRouteVariable("id", r)// 2. 讀取對應的文章數據article, err := getArticleByID(id)// 3. 如果出現錯誤if err != nil {if err == sql.ErrNoRows {// 3.1 數據未找到w.WriteHeader(http.StatusNotFound)fmt.Fprint(w, "404 文章未找到")} else {// 3.2 數據庫錯誤checkError(err)w.WriteHeader(http.StatusInternalServerError)fmt.Fprint(w, "500 服務器內部錯誤")}} else {// 4. 未出現錯誤,執行刪除操作rowsAffected, err := article.Delete()// 4.1 發生錯誤if err != nil {// 應該是 SQL 報錯了checkError(err)w.WriteHeader(http.StatusInternalServerError)fmt.Fprint(w, "500 服務器內部錯誤")} else {// 4.2 未發生錯誤if rowsAffected > 0 {// 重定向到文章列表頁indexURL, _ := router.Get("articles.index").URL()http.Redirect(w, r, indexURL.String(), http.StatusFound)} else {// Edge casew.WriteHeader(http.StatusNotFound)fmt.Fprint(w, "404 文章未找到")}}}
}
添加Article 的 Delete() 方法 ,上面代碼塊用到了Delete方法
// // 為 Article 添加一個 Delete 方法,刪除文章
func (a Article) Delete() (rowsAffected int64, err error) {rs, err := db.Exec("DELETE FROM articles WHERE id = " + strconv.FormatInt(a.ID, 10))if err != nil {return 0, err}// √ 刪除成功if n, _ := rs.RowsAffected(); n > 0 {return n, nil}return 0, nil
}
(3)文章詳情頁面添加刪除按鈕
.
.
.
func articlesShowHandler(w http.ResponseWriter, r *http.Request) {...// 3. 如果出現錯誤if err != nil {...} else {// 4. 讀取成功,顯示文章tmpl, err := template.New("show.gohtml").Funcs(template.FuncMap{"RouteName2URL": RouteName2URL,"Int64ToString": Int64ToString,}).ParseFiles("resources/views/articles/show.gohtml")checkError(err)err = tmpl.Execute(w, article)checkError(err)}
}
template.New() 先初始化,然后使用 Funcs() 注冊函數,再使用 ParseFiles (),需要注意的是 New() 的參數是模板名稱,需要對應 ParseFiles() 中的文件名,否則會無法正確讀取到模板,最終顯示空白頁面。
創建上面代碼中的兩個函數RouteName2URL 和 Int64ToString
.
.
.
// RouteName2URL 通過路由名稱來獲取 URL
func RouteName2URL(routeName string, pairs ...string) string {url, err := router.Get(routeName).URL(pairs...)if err != nil {checkError(err)return ""}return url.String()
}// Int64ToString 將 int64 轉換為 string
func Int64ToString(num int64) string {return strconv.FormatInt(num, 10)
}func (a Article) Delete() (rowsAffected int64, err error) {
.
.
.
修改模板 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>{{/* 構建刪除按鈕 */}}{{ $idString := Int64ToString .ID }}<form action="{{ RouteName2URL "articles.delete" "id" $idString }}" method="post"><button type="submit" onclick="return confirm('刪除動作不可逆,請確定是否繼續')">刪除</button></form></body></html>
打開articles.show文章詳情頁localhost:3000/articles/4
點擊刪除,確定刪除