Golang要操作mysql數據庫,首先需要在當期系統配置GOPATH,因為需要使用go get命令把驅動包下載到GOPATH下使用。
首先配置好你的GOPATH,執行以下命令,下載安裝mysql驅動,下載完成之后會在GOPATH下的src/github.com目錄下
//路由文件
package routers import ( "github.com/astaxie/beego"
"mypro/controllers" ) func init() { beego.Router("/", &controllers.MainController{}) beego.Router("/collection", &controllers.CollectionController{}) beego.Router("/getmovieinfo/?:id", &controllers.GetMovieInfoController{},"get:Get") beego.Router("/postmovieinfo", &controllers.GetMovieInfoController{},"post:Post") //post
beego.Router("/editmovieinfo/?:id", &controllers.GetMovieInfoController{},"get:Edit") //post
beego.Router("/editmovieinfo", &controllers.GetMovieInfoController{},"post:EditPost") //post
beego.Router("/deletemovieinfo/?:id", &controllers.GetMovieInfoController{},"get:Delete") //post
beego.Router("/addmovieinfo", &controllers.GetMovieInfoController{},"post:Add") //post
beego.Router("/addmovieinfoview", &controllers.GetMovieInfoController{},"get:AddView") //post
}
//控制器文件
package controllers import ( "fmt"
"github.com/astaxie/beego"
"mypro/models"
"strings" ) type GetMovieInfoController struct { beego.Controller } type MovieInfo struct { Id int64 Movie_name string Movie_director string } type JsonpData struct { Code int Msg string } //獲取列表數據展示
func (c *GetMovieInfoController) Get() { ids := []string{"11", "9", "10"} db := models.ConnectDb(); defer db.Close() idStr := strings.Join(ids, "','") sqlText := "select id,movie_name,movie_director from movie_info where id in ('%s')" sqlText = fmt.Sprintf(sqlText, idStr) rows,err := db.Query(sqlText) item := MovieInfo{} list := []MovieInfo{} for rows.Next(){ var mid int64 var movie_name, movie_director string err = rows.Scan(&mid,&movie_name,&movie_director) if err != nil { panic(err.Error()) } item.Id = mid item.Movie_name = movie_name item.Movie_director = movie_director list = append(list,item) } c.Data["List"] = list c.Data["Title"] = "電影列表" c.TplName = "get.tpl" } //編輯查看數據地址
func (c *GetMovieInfoController) Edit() { movie_id := c.GetString(":id") db := models.ConnectDb(); defer db.Close() var Info MovieInfo err := db.QueryRow("select id,movie_name,movie_director from movie_info where id = ?",movie_id).Scan(&Info.Id, &Info.Movie_name, &Info.Movie_director) if err != nil { panic(err.Error()) } c.Data["info"] = Info c.TplName = "Edit.tpl" } //編輯提交地址
func (c *GetMovieInfoController ) EditPost() { Movie_name:=c.GetString("name") Movie_director:=c.GetString("director") Id:=c.GetString("id") db := models.ConnectDb(); defer db.Close() res,_ := db.Exec("update movie_info set movie_name =?,movie_director = ? where id = ?",Movie_name,Movie_director,Id) num, _ := res.RowsAffected() //影響行數
if num >0 { c.Redirect("/editmovieinfo/"+Id,301) } else { c.Redirect("http://www.baidu.com",301) } } //刪除動作提交
func (c *GetMovieInfoController ) Delete() { Id:=c.GetString(":id") db := models.ConnectDb(); defer db.Close() res,err := db.Exec("delete from movie_info where id = ?",Id) if err != nil { panic(err.Error()) } num, _ := res.RowsAffected() //影響行數
if num >0 { c.Redirect("/getmovieinfo",301) } else { c.Redirect("http://www.baidu.com",301) } } //增加視圖
func (c *GetMovieInfoController ) AddView() { c.TplName="add.tpl" } //增加提交操作地址
func (c *GetMovieInfoController ) Add() { Movie_name:=c.GetString("name") Movie_director:=c.GetString("director") db := models.ConnectDb(); defer db.Close() res,err := db.Exec("insert into movie_info ( movie_name ,movie_director) values (?,?)",Movie_name,Movie_director) if err != nil { panic(err.Error()) } num, _ := res.RowsAffected() //影響行數
if num >0 { c.Redirect("/getmovieinfo",301) } else { c.Redirect("http://www.baidu.com",301) } }
說明:
數據庫查詢的一般步驟如下:
- 調用 db.Query 執行 SQL 語句, 此方法會返回一個 Rows 作為查詢的結果
- 通過 rows.Next() 迭代查詢數據.
- 通過 rows.Scan() 讀取每一行的值
- 調用 db.Close() 關閉查詢
- rows.Scan 參數的順序很重要, 需要和查詢的結果的column對應. 例如 “SELECT * From user where age >=20 AND age < 30” 查詢的行的 column 順序是 “id, name, age” 和插入操作順序相同, 因此 rows.Scan 也需要按照此順序 rows.Scan(&id, &name, &age), 不然會造成數據讀取的錯位.
- 因為golang是強類型語言,所以查詢數據時先定義數據類型,但是查詢數據庫中的數據存在三種可能:存在值,存在零值,未賦值NULL 三種狀態, 因為可以將待查詢的數據類型定義為sql.Nullxxx類型,可以通過判斷Valid值來判斷查詢到的值是否為賦值狀態還是未賦值NULL狀態.
- 每次db.Query操作后, 都建議調用rows.Close(). 因為 db.Query() 會從數據庫連接池中獲取一個連接, 這個底層連接在結果集(rows)未關閉前會被標記為處於繁忙狀態。當遍歷讀到最后一條記錄時,會發生一個內部EOF錯誤,自動調用rows.Close(),但如果提前退出循環,rows不會關閉,連接不會回到連接池中,連接也不會關閉, 則此連接會一直被占用. 因此通常我們使用 defer rows.Close() 來確保數據庫連接可以正確放回到連接池中; 不過閱讀源碼發現rows.Close()操作是冪等操作,即一個冪等操作的特點是其任意多次執行所產生的影響均與一次執行的影響相同, 所以即便對已關閉的rows再執行close()也沒關系.
