使用Go語言建立簡單的CRUD增刪改查

banq發表於2017-01-09

用Go構建一個簡單的CRUD應用
Go是一個偉大的程式語言,這裡使用sqlite資料庫建立一個簡單的CRUD應用。

首先,我們需要知道使用資料庫的方式。 Go提供了一個名為database / sql的內建包,提供了一個圍繞SQL或類SQL資料庫的輕量級介面,它必須與資料庫驅動程式結合使用,在本文中,我們將使用sqlite資料庫,和選擇https://github.com/mattn/go-sqlite3

接下來,我們將建立使用的模型,我建立了一個struct如下:

type Cost struct {
	Id int64 `json:"id"`
	ElectricAmount int64 `json:"electric_amount"`
	ElectricPrice float64 `json:"electric_price"`
	WaterAmount int64 `json:"water_amount"`
	WaterPrice float64 `json:"water_price"`
	CheckedDate string `json:"checked_date"`
}
<p class="indent">

在上面的程式碼中我使用struct標籤,這是一個有用的功能,幫助你序列化到json到響應。

接下來,我們將在main函式中連線到資料庫,如下所示:

db, err = sql.Open("sqlite3", "db.sqlite3")
	if err != nil {
		panic(err)
	}
	defer db.Close()
	// test connection
	err = db.Ping()
	if err != nil {
		panic(err)
	}
<p class="indent">


CRUD的四個任務是建立,讀取,更新和刪除。 我們將後面將建立每個對應的處理程式。

func listHandler(w http.ResponseWriter, r *http.Request) {
	if r.Method != "GET" {
		http.Error(w, "Method not allowed", http.StatusBadRequest)
	}
	rows, err := db.Query("SELECT * FROM cost")
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
	var funcMap = template.FuncMap{
		"multiplication": func(n float64, f float64) float64 {
			return n * f
		},
		"addOne": func(n int) int {
			return n + 1
		},
	}
	var costs []Cost
	var cost Cost
	for rows.Next() {
		err = rows.Scan(&cost.Id, &cost.ElectricAmount,
			&cost.ElectricPrice, &cost.WaterAmount, &cost.WaterPrice, &cost.CheckedDate)
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
		}
		costs = append(costs, cost)
	}
	//t, err := template.ParseFiles("tmpl/list.html")
	t, err := template.New("list.html").Funcs(funcMap).ParseFiles("tmpl/list.html")
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
	err = t.Execute(w, costs)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}

}

func createHandler(w http.ResponseWriter, r *http.Request) {
	if r.Method != "POST" {
		http.ServeFile(w, r, "tmpl/create.html")
		return
	}
	var cost Cost
	cost.ElectricAmount, _ = strconv.ParseInt(r.FormValue("ElectricAmount"), 10, 64)
	cost.ElectricPrice, _ = strconv.ParseFloat(r.FormValue("ElectricPrice"), 64)
	cost.WaterAmount, _ = strconv.ParseInt(r.FormValue("WaterAmount"), 10, 64)
	cost.WaterPrice, _ = strconv.ParseFloat(r.FormValue("WaterPrice"), 64)
	cost.CheckedDate = r.FormValue("CheckedDate")
	fmt.Println(cost)

	// Save to database
	stmt, err := db.Prepare(`
		INSERT INTO cost(electric_amount, electric_price, water_amount, water_price, checked_date)
		VALUES(?, ?, ?, ?, ?)
	`)
	if err != nil {
		fmt.Println("Prepare query error")
		panic(err)
	}
	_, err = stmt.Exec(cost.ElectricAmount, cost.ElectricPrice,
				cost.WaterAmount, cost.WaterPrice, cost.CheckedDate)
	if err != nil {
		fmt.Println("Execute query error")
		panic(err)
	}
	http.Redirect(w, r, "/list", 301)
}

func updateHandler(w http.ResponseWriter, r *http.Request) {
	if r.Method != "POST" {
		http.Error(w, "Method is not allowed", http.StatusBadRequest)
	}
	var cost Cost
	cost.Id, _ = strconv.ParseInt(r.FormValue("Id"), 10, 64)
	cost.ElectricAmount, _ = strconv.ParseInt(r.FormValue("ElectricAmount"), 10, 64)
	cost.ElectricPrice, _ = strconv.ParseFloat(r.FormValue("ElectricPrice"), 64)
	cost.WaterAmount, _ = strconv.ParseInt(r.FormValue("WaterAmount"), 10, 64)
	cost.WaterPrice, _ = strconv.ParseFloat(r.FormValue("WaterPrice"), 64)
	cost.CheckedDate = r.FormValue("CheckedDate")
	fmt.Println(cost)
	stmt, err := db.Prepare(`
		UPDATE cost SET electric_amount=?, electric_price=?, water_amount=?, water_price=?, checked_date=?
		WHERE id=?
	`)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
	res, err := stmt.Exec(cost.ElectricAmount, cost.ElectricPrice,
		cost.WaterAmount, cost.WaterPrice, cost.CheckedDate, cost.Id)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
	_, err = res.RowsAffected()
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
	http.Redirect(w, r, "/list", 301)
}

func deleteHandler(w http.ResponseWriter, r *http.Request) {
	if r.Method != "POST" {
		http.Error(w, "Method not allowed", http.StatusBadRequest)
	}
	var costId, _ = strconv.ParseInt(r.FormValue("Id"), 10, 64)
	stmt, err := db.Prepare("DELETE FROM cost WHERE id=?")
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
	res, err := stmt.Exec(costId)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
	_, err = res.RowsAffected()
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
	http.Redirect(w, r, "/list", 301)

}
<p class="indent">


最後讓我們在main函式上為每個上述處理程式建立一個路由

// route
	http.HandleFunc("/list", listHandler)
	http.HandleFunc("/create", createHandler)
	http.HandleFunc("/update", updateHandler)
	http.HandleFunc("/delete", deleteHandler)
	http.ListenAndServe(":3333", nil)
<p class="indent">



完整的程式碼和模板請參見https://github.com/thanhngvpt/famcost


Build a simple CRUD with Go – Medium

相關文章