詳細實現方式以及源碼下載請前往 https://www.passerma.com/article/72
beego入門到實戰
一、安裝beego和bee工具
使用官網最新的v2版本goget github.com/beego/beego/v2goget github.com/beego/bee/v2
或者,使用的是v1版本
goget github.com/astaxie/beegogoget github.com/beego/bee
二、使用bee工具構建項目框架
beenewbeego_project(項目名)
將會創建一個典型的MVC框架應用
或者
beeapibeego_project(項目名)
將構建一個純后端項目
直接運行 bee 查看更多命令
這里使用 bee new 來構建MVC項目
三、啟動項目開始愉快的coding
1.進入項目目錄
使用 bee run 啟動或者 go run 啟動
建議使用 bee run ,這樣會監聽代碼是否修改,自動重啟
2.開始coding
四、路由詳解
1.固定路由
1.響應所有類型的請求
beego.Router("/", &controllers.MainController{})
對應的Controller如下
package controllersimport ("github.com/astaxie/beego" )type MainControllerstruct { beego.Controller }func(c *MainController)Get() { c.Ctx.WriteString("Get") }func(c *MainController)Post() { c.Ctx.WriteString("Post") }func(c *MainController)Put() { c.Ctx.WriteString("Put") }func(c *MainController)Delete() { c.Ctx.WriteString("Delete") }
我們在調用get方法時,會執行對應控制器的get方法,同理post則會執行post方法,其他方法同樣如此
2.響應基本路由
即將Router改為對應的方法類型,比如get和post
package routers import ("github.com/astaxie/beego""github.com/astaxie/beego/context" ) func init() { beego.Get("/",func(ctx*context.Context){ ctx.Output.Body([]byte("get")) }) beego.Post("/",func(ctx*context.Context){ ctx.Output.Body([]byte("post")) }) }
支持以下所有類型
beego.Get(router, beego.FilterFunc)
beego.Post(router, beego.FilterFunc)
beego.Put(router, beego.FilterFunc)
beego.Patch(router, beego.FilterFunc)
beego.Head(router, beego.FilterFunc)
beego.Options(router, beego.FilterFunc)
beego.Delete(router, beego.FilterFunc)
beego.Any(router, beego.FilterFunc)
3.更改對應的響應方法
beego.Router("/", &controllers.MainController{}, "get:MyGet;post:MyPost")
beego.Router("/", &controllers.MainController{}, "get,post:MyPost")
beego.Router("/", &controllers.MainController{}, "*:MyPost")
如果同時存在 * 和對應的請求方法,那么優先執行對應請求的方法,例如同時注冊了以下路由:
beego.Router("/",&controllers.MainController{},"*:AllFunc;post:MyPost")
那么執行POST請求的時候,執行MyPost而不執行 AllFunc
2.正則路由
beego.Router("/?:id", &controllers.MainController{})
匹配"/"或者"/123",此時變量":id"值為即為"/"后面的參數,及123
beego.Router("/:id", &controllers.MainController{})
匹配"/123","/"后必須要參數,此時變量":id"值為即為"/"后面的參數,及123
beego.Router("/:id([0-9]+)", &controllers.MainController{})
自定義正則匹配,只能匹配數字0-9, 例如對於"/123"可以匹配成功,此時id值為123
beego.Router("/*.*", &controllers.MainController{})
對於"/123.png"可以匹配成功,此時變量":path"值為"123",":ext"值為"png"
beego.Router("/*", &controllers.MainController{})
全匹配,對於"/123"可以匹配成功,此時變量":splat"值為" 123
beego.Router("/:id:int", &controllers.MainController{})
int類型設置方式,匹配 :id為int類型,也可其他類型,如string類型,”/:id:string“,匹配 :id為string類型
beego.Router("/:id.html", &controllers.MainController{})
帶有前綴的匹配,例如對於"/123.html"可以匹配成功,此時:id為123
可以在Controller中通過如下方式獲取上面的變量
id := c.Ctx.Input.Param(":id")
id := c.Ctx.Input.Param(":splat")
id := c.Ctx.Input.Param(":path")
id := c.Ctx.Input.Param(":ext")
3.自動路由
注冊路由的時候不需要指定url,只需要注冊控制器即可beego.AutoRouter(&controllers.MainController{})
/main/api 調用MainController中的 api 方法
/main/api2 調用MainController中的 api2 方法
除了前綴兩個 /:controller/:method 的匹配之外,剩下的參數beego會幫解析為參數
保存在Ctx.Input.Params當中:
/main/api/1/2/3 調用MainController中的api方法,
參數如下 map[0:1 1:2 2:3]
4.注解路由
// CMS API type CMSController struct { web.Controller } // @router /staticblock/:key [get] func (this *CMSController) StaticBlock() { } // @router /all/:key [get] func (this *CMSController) AllBlock() { } web.Include(&CMSController{})
5.命名空間
//初始化 namespace ns := web.NewNamespace("/v1", web.NSCond(func(ctx *context.Context) bool { if ctx.Input.Domain() == "api.beego.me" { return true } return false }), web.NSBefore(auth), web.NSGet("/notallowed", func(ctx *context.Context) { ctx.Output.Body([]byte("notAllowed")) }), web.NSRouter("/version", &AdminController{}, "get:ShowAPIVersion"), web.NSRouter("/changepassword", &UserController{}), web.NSNamespace("/shop", web.NSBefore(sentry), web.NSGet("/:id", func(ctx *context.Context) { ctx.Output.Body([]byte("notAllowed")) }), ), web.NSNamespace("/cms", web.NSInclude( &controllers.MainController{}, &controllers.CMSController{}, &controllers.BlockController{}, ), ), ) //注冊 namespace web.AddNamespace(ns)
五、解析參數
1.獲取url上的參數,?后面的
GetString獲取數據:
路由: beego.Router("/", &controllers.MainController{})
訪問路徑:http://127.0.0.1:8080/?id=111
獲取數據:
id := c.GetString("id")
id2 := c.Input().Get("id")
這種方式不行:
id3 := c.Ctx.Input.Param(":id")
2.獲取url上的參數,/:id類型的
路由:beego.Router("/?:id:int", &controllers.MainController{})
訪問路徑:http://127.0.0.1:8080/111
獲取數據:
id := c.GetString(":id")
id2 := c.Ctx.Input.Param(":id")
這種方式不行:
id3 := c.Input().Get(":id")
3.獲取form表單數據
1.直接獲取
GetString(key string) string
GetStrings(key string) []string
GetInt(key string) (int64, error) --返回兩個值
GetBool(key string) (bool, error) --返回兩個值
GetFloat(key string) (float64, error) --返回兩個值
舉例:
前端form表單:
姓名1:<input type="text" name="name">
姓名2:<input type="text" name="name">
年齡:<input type="text" name="age">
是: <input type="radio" name="is_true" value="true">
價格: <input type="text" name="price">
獲取數據:
name := c.Input().Get("name") 獲取的是第一個name的值
names := c.GetStrings("name") 獲取所有的name的值,是個數組
age, err := c.GetInt("age")
is_true , err := c.GetBool("is_true")
price , err := c.GetFloat("price")
2..解析到結構體
type Student struct {
Id int
Name string `form:"user_name"`
Password string `form:"password"`
}
func (s *StudentController) Post() {
student := Student{}
if err := s.ParseForm(&student); err != nil {
return
}
fmt.Println(student)
fmt.Println(student.Name)
fmt.Println(student.Age)
fmt.Println(student.Addr)
}
4.獲取json數據
在app.conf配置文件中設置 copyrequestbody = true在controller中使用Golang標准庫json包來解析json數據封裝到stuct結構體
package controllers
import (
"encoding/json"
"fmt"
beego "github.com/beego/beego/v2/server/web"
)
type MainController struct {
beego.Controller
}
type LoginData struct {
Username string
Passwd string `json:"password"`
}
func (c *MainController) Post() {
var loginData LoginData
data := c.Ctx.Input.RequestBody
if err := json.Unmarshal(data, &loginData); err != nil {
fmt.Println("json.Unmarshal is err:", err.Error())
}
fmt.Println(loginData)
c.Ctx.WriteString(loginData.Username)
}
5.獲取文件
f, h, _ := c.GetFile("file") defer f.Close() c.SaveToFile("file", "static/down/" + h.Filename) // 保存位置在 static/upload, 沒有文件夾要先創建
6.表單校驗
安裝
go get github.com/beego/beego/v2/core/validation
使用
type UserValid struct { Id int `form:"-"` Name string `form:"username" valid:"Required"` Passwd string } func (c ParamsController) Required() { var user UserValid c.ParseForm(&user) valid := validation.Validation{} var message = map[string]string{ "Required":"不能為空", } validation.SetDefaultMessage(message) b, err := valid.Valid(&user) valid.Required(user.Passwd, "passwd") valid.Required(user.Passwd, "密碼").Message("不能為空!!!") err := valid.HasErrors() if err { // 如果有錯誤信息,證明驗證沒通過 // 打印錯誤信息 for _, err := range valid.Errors { fmt.Println(err.Key, err.Message) } } }
7.過濾器
func FilterUStatic(c *context.Context) { fmt.Println("BeforeStatic", c.Request.RequestURI) } func FilterRouter(c *context.Context) { data := map[string]interface{}{"ErrCode": 0, "ErrMsg": "ok", "data": 123} c.Output.JSON(data,false,false) } beego.InsertFilter("/*", beego.BeforeStatic, FilterUStatic) beego.InsertFilter("/*", beego.BeforeRouter, FilterRouter) // 能拿到session
六、返回數據
1.返回json數據
package controllers
import (
beego "github.com/beego/beego/v2/server/web"
)
type MainController struct {
beego.Controller
}
type SendMsg struct {
ErrCode string
ErrMsg string
Data []string `json:"data_info"`//key重命名,最外面是反引號
}
func (c *MainController) Post() {
data := &SendMsg{"0", "ok", []string{"passerma","com"}}
c.Data["json"] = data
c.ServeJSON()
}
返回結果
七、操作session和數據庫
1.操作session
1).直接使用session
session主要是和cookie一起使用的在app.conf配置文件中設置 sessionOn= true
或者使用
beego.BConfig.WebConfig.Session.SessionOn = true
session 有幾個方便的方法:
SetSession(name string, value interface{})
GetSession(name string) interface{}
DelSession(name string)
SessionRegenerateID()
DestroySession()session
操作主要有設置 session、獲取 session、刪除 session。
關於 Session模塊和cookie模塊使用中的一些參數設置:
設置 Session 過期的時間
beego.BConfig.WebConfig.Session.SessionGCMaxLifetime 默認值是 3600 秒
設置 cookie 的過期時間
beego.BConfig.WebConfig.Session.SessionCookieLifeTime
設置sessionid加密算法
beego.BConfig.WebConfig.Session.SessionHashFunc 默認值為 sha1
修改sessionkey
beego.BConfig.WebConfig.Session.SessionHashKey默認的 key 是 beegoserversessionkey
修改該參數設置 cookies 的名字
beego.BConfig.WebConfig.Session.SessionNameSession 默認是保存在用戶的瀏覽器 cookies 里面的,默認名是 beegosessionID
以上也可通過配置文件修改
2).session鏈接redis
從beego1.1.3版本開始移除了第三方依賴庫,因此需要安裝redis包go get -u github.com/beego/beego/v2/session/redis
或者
go get -u github.com/astaxie/beego/session/redis
引入庫
import _ "github.com/beego/beego/v2/session/redis"
或者
import _ "github.com/astaxie/beego/session/redis"
鏈接到redis
func main() {
beego.BConfig.WebConfig.Session.SessionProvider = "redis"
// "127.0.0.1:6379,1000,$password"
//其中127.0.0.1:6379為ip和端口,1000為連接池,最后一個為redis密碼
beego.BConfig.WebConfig.Session.SessionProviderConfig = "127.0.0.1:6379"
beego.Run()
}
2.操作數據庫(MySQL)
1.連接數據庫
1).安裝orm和MySQL驅動orm安裝
go get github.com/beego/beego/v2/client/orm
或者
go get github.com/astaxie/beego/orm
MySQL驅動安裝
go get github.com/go-sql-driver/mysql
2).連接數據庫(必須注冊一個別名為default的數據庫)
orm.RegisterDriver("mysql", orm.DRMySQL)
orm.RegisterDataBase("default", "mysql", "用戶名:密碼@tcp(IP:端口號)/數據庫?charset=utf8",30,30)
參數一: 數據庫的別名,用來在 ORM 中切換數據庫使用
參數二: 驅動名稱
參數三: 對應的鏈接字符串
參數四(可選):設置最大空閑連接或根據數據庫別名設置:orm.SetMaxIdleConns(“default”, 30)
參數五(可選):設置最大數據庫連接或根據數據庫別名設置: orm.SetMaxOpenConns(“default”, 30)
3).注冊模型
orm.RegisterModel(new(Users))
4).操作數據庫例子
先在main.go里連接數據庫
package main
import (
_ "beegoV2/routers"
beego "github.com/beego/beego/v2/server/web"
"github.com/beego/beego/v2/orm"
_ "github.com/go-sql-driver/mysql"
)
func init() {
orm.RegisterDriver("mysql", orm.DRMySQL)
orm.RegisterDataBase("default",
"mysql","root:admin_123@tcp(127.0.0.1:3306)/go_test?charset=utf8")
}
func main() {
beego.Run()
}
在models里注冊模型
package models
import "github.com/beego/beego/v2/orm"
type Users struct {
Id int `orm:"pk;auto"`
Username string
Password string `orm:"column(passwd)"`
}
func init() {
orm.RegisterModel(new(Users))
}
在controllers里操作數據
func (c *UserController) Post() {
var useData models.Users // 查詢到的用戶
o := orm.NewOrm()
qs := o.QueryTable(new(models.Users))
passwd := utils.GetMd5(123456) // 得到加密后的密碼
userErr := qs.Filter("Username","passerma").Filter("Password",passwd).One(&useData)
if userErr != nil {
fmt.Println(useData)
} else {
fmt.Println(err.Error())
}
}
2.自動建表
前提:數據庫已注冊:orm.RegisterDataBase
模型已注冊: orm.RegisterModel
func init() {
orm.RegisterDriver("mysql", orm.DRMySQL)
orm.RegisterDataBase("default","mysql","root:admin_123@tcp(127.0.0.1:3306)/go_test?charset=utf8")
name := "default" // 指定數據庫別名,默認使用別名為 default
force := false // 刪除表后再創建,默認為true
verbose := true // 可以查看執行的 sql 語句
err := orm.RunSyncdb(name,force,verbose)
if err != nil {
panic(err)
}
}
func main() {
orm.RunCommand()
beego.Run()
}
八、日志模塊
1.輸出到文件
logs.SetLogger(logs.AdapterFile, {"filename":"test.log"})
參數:
filename 保存的文件名
maxlines 每個文件保存的最大行數,默認值 1000000
maxsize 每個文件保存的最大尺寸,默認值是 1 << 28, //256 MB 2^28 1<< 3 2^3
daily 是否按照每天 logrotate,默認是
truemaxdays 文件最多保存多少天,默認保存 7 天
rotate 是否開啟 logrotate,默認是
truelevel 日志保存的時候的級別,默認是 Trace 級別
perm 日志文件權限 4(讀權限)2(寫權限)1(執行權限)
multifile
多文件日志寫入,對號入座寫入,比如test.error.log,err.debug.log
logs.SetLogger(logs.AdapterMultiFile, {
"filename":"test.log",
"separate":["emergency", "alert", "critical", "error", "warning", "notice", "info", "debug"]
}
)
2.郵件發送
logs.SetLogger(logs.AdapterMail,{
"username":"xxx@qq.com", "password":"認證密碼", "host":"smtp.qq.com:587", "fromAddress":"xxx@qq.com", "sendTos":["xxx@qq.com"] })
九、部署
1.獨立部署
bee pack -be GOOS=linux
(打包到linux上部署命令)
bee pack -be GOOS=window
(打包到windows上部署命令)
會生成tar.gz包
復制到服務器解壓 tar zxvf tar.gz
增加解壓后的二進制文件的可執行權限 chmod +x go_pkg
啟動 nohup ./go_pkg &
2Supervisor部署
[program:beepkg] directory = /opt/app/beepkg command = /opt/app/beepkg/beepkg autostart = true startsecs = 5 user = root redirect_stderr = true stdout_logfile = /var/log/supervisord/beepkg.log
啟動進程 supervisorctl start beepkg
詳細實現方式以及源碼下載請前往 https://www.passerma.com/article/72