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