上一篇讲了查询图书并且分页,那是在图书管理那里,那么我们接着讲图书的管理。
完成后项目结构
实现的功能如下:
1、删除图书
在bookhandler.go新加一个函数
func DeleteBook(w http.ResponseWriter, r *http.Request) {
bookID := r.FormValue("bookId")
dao.DeleteBook(bookID)
GetPageBooks(w, r)
}
代码的最后一行,在删除完一本图书之后,我们再调用上一篇讲的分页函数,这样重新显示该页面
在bookdao.go里新增删除图书DeleteBook()函数
func DeleteBook(bookID string) error {
sqlStr := "delete from books where id = ?"
_, err := utils.Db.Exec(sqlStr, bookID)
if err != nil {
return err
}
return nil
}
也是非常的简单,调用sql语句就可以
2、更新图书
我们有专门更新图书的页面如下 只要在“修改”这个超链接,加上我们要用的信息
<td><a href="/toUpdateBookPage?bookId={{.ID}}">修改</a></td>
“/toUpdateBookPage?bookId={{.ID}}” 1、需要在main中加入/toUpdateBookPage的路由,再进入控制器处理 2、?bookId={{.ID}就是我们要获得的有用的信息了 我们可以根据book.ID来从数据库获得book对象,然后更新图书信息之后,可以重新写入数据库
http.HandleFunc("/toUpdateBookPage", controller.ToUpdateBookPage)
之后再bookcontroller里的函数就可以这么写了,跳转到book_edit.html
func ToUpdateBookPage(w http.ResponseWriter, r *http.Request) {
bookID := r.FormValue("bookId")
book, _ := dao.GetBookByID(bookID)
if book.ID > 0 {
t := template.Must(template.ParseFiles("views/pages/manager/book_edit.html"))
t.Execute(w, book)
} else {
t := template.Must(template.ParseFiles("views/pages/manager/book_edit.html"))
t.Execute(w, "")
}
}
book, _ := dao.GetBookByID(bookID) 在数据库中通过bookID查找到book, 如果存在这么一本书,那么久前往修改页面。 不存在:是为后面新增图书做的准备,与现在这个功能无关
bookdao新增 GetBookByID()函数
func GetBookByID(bookID string) (*model.Book, error) {
sqlStr := "select id,title,author,price,sales,stock,img_path from books where id = ?"
row := utils.Db.QueryRow(sqlStr, bookID)
book := &model.Book{}
row.Scan(&book.ID, &book.Title, &book.Author, &book.Price, &book.Sales, &book.Stock, &book.ImgPath)
return book, nil
}
在更新图书界面 bookedi.html,点击提交之后
<form action="/updateOraddBook" method="POST">
<input type="hidden" name="bookId" value="{{.ID}}" />
<td><input name="title" type="text" value="{{.Title}}"/></td>
<td><input name="price" type="text" value="{{.Price}}"/></td>
<td><input name="author" type="text" value="{{.Author}}"/></td>
<td><input name="sales" type="text" value="{{.Sales}}"/></td>
<td><input name="stock" type="text" value="{{.Stock}}"/></td>
main中添加路由
http.HandleFunc("/updateOraddBook", controller.UpdateOrAddBook)
UpdateOrAddBook ( ) 就可以用 bookID := r.PostFormValue(“bookId”) 来获取信息了
func UpdateOrAddBook(w http.ResponseWriter, r *http.Request) {
bookID := r.PostFormValue("bookId")
title := r.PostFormValue("title")
author := r.PostFormValue("author")
price := r.PostFormValue("price")
sales := r.PostFormValue("sales")
stock := r.PostFormValue("stock")
fPrice, _ := strconv.ParseFloat(price, 64)
iSales, _ := strconv.ParseInt(sales, 10, 0)
iStock, _ := strconv.ParseInt(stock, 10, 0)
ibookID, _ := strconv.ParseInt(bookID, 10, 0)
book := &model.Book{
ID: int(ibookID),
Title: title,
Author: author,
Price: fPrice,
Sales: int(iSales),
Stock: int(iStock),
ImgPath: "/static/img/default.jpg",
}
if book.ID > 0 {
dao.UpdateBook(book)
} else {
dao.AddBook(book)
}
GetPageBooks(w, r)
}
那么更新图书就简单了,dao.UpdateBook(book) 传来了book对象,调用sql就可以了
func UpdateBook(b *model.Book) error {
sqlStr := "update books set title=?,author=?,price=?,sales=?,stock=? where id=?"
_, err := utils.Db.Exec(sqlStr, b.Title, b.Author, b.Price, b.Sales, b.Stock, b.ID)
if err != nil {
return err
}
return nil
}
3、新增图书
我们可以共用UpdateOrAddBook ( ) ,因为都是在编辑图书页面,只要在UpdateOrAddBook ( ) 增加判断就可以了
if book.ID > 0 {
dao.UpdateBook(book)
} else {
dao.AddBook(book)
}
GetPageBooks(w, r)
如果之前就在数据库中有记录,1、那么就是更新书,调用dao.UpdateBook(book)在数据库中update 2、否则就是新增书,dao.AddBook(book)在数据库中insert
func AddBook(b *model.Book) error {
slqStr := "insert into books(title,author,price,sales,stock,img_path) values(?,?,?,?,?,?)"
_, err := utils.Db.Exec(slqStr, b.Title, b.Author, b.Price, b.Sales, b.Stock, b.ImgPath)
if err != nil {
return err
}
return nil
}
注意到book_edit有一个有趣的点 bookhandle.go里的ToUpdateBookPage()(也就是上面那个)
if book.ID > 0 {
t := template.Must(template.ParseFiles("views/pages/manager/book_edit.html"))
t.Execute(w, book)
} else {
t := template.Must(template.ParseFiles("views/pages/manager/book_edit.html"))
t.Execute(w, "")
}
在更新书的时候: t.Execute(w, book),带着book进入book_edit.html 在新增书的时候 t.Execute(w, “”),传的值是空。 所以这两个页面就不一样了,其实是同一个文件
<div id="main">
<form action="/updateOraddBook" method="POST">
<table>
<tr>
<td>名称</td>
<td>价格</td>
<td>作者</td>
<td>销量</td>
<td>库存</td>
<td colspan="2">操作</td>
</tr>
<tr>
{{if .}}
<input type="hidden" name="bookId" value="{{.ID}}" />
<td><input name="title" type="text" value="{{.Title}}"/></td>
<td><input name="price" type="text" value="{{.Price}}"/></td>
<td><input name="author" type="text" value="{{.Author}}"/></td>
<td><input name="sales" type="text" value="{{.Sales}}"/></td>
<td><input name="stock" type="text" value="{{.Stock}}"/></td>
{{else}}
<td><input name="title" type="text" /></td>
<td><input name="price" type="text" /></td>
<td><input name="author" type="text" /></td>
<td><input name="sales" type="text" /></td>
<td><input name="stock" type="text" /></td>
{{end}}
<td><input type="submit" value="提交"/></td>
</tr>
</table>
</form>
</div>
{{if .}} 如果传入book,就显示图书的信息 {{else}} 没传就是空白
总结
增删改查是最基本的数据库用法,在现实的应用中也是普遍的。 业务的逻辑大差不差, 都是在html页面点击超链接或者按钮, 它们都包含了路由的信息 (如/toUpdateBookPage还有必要的信息,如book的ID),通过main中的路由,找到对应的controller,再通过数据库的改动,实现目的
2022.4.8 01:40。 最近挺晚睡觉的,夜深人静适合思考
|