beego入门到实战
2021-04-05 11:31820
一、安装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