Beego
Beego
Beego介绍
beego是一个快速发开Go应用的HTTP框架
可以用来快速开发API、Web及后端服务等各种应用
GitHub地址:https://github.com/beego/beego
中文文档地址:https://beego.gocn.vip/beego/zh/developing/
安装bee工具
- 下载bee工具(Mac)(解决zsh: command not found: bee问题)
go get -u github.com/beego/bee/v2@master
- 安装完之后,bee可执行文件默认存放在
$GOPATH/bin
里面,需要把$GOPATH/bin
添加到环境变量中,才可以进行下一步 - 终端执行
go env
, 找到对应的GOMODCACHE=
所在的路径(/Users/yama/go/pkg/mod/github.com/beego/bee/v2@v2.0.4
)然后执行go build
,会生成一个bee的可执行文件,然后复制到/usr/local/bin
目录下,再次执行bee version
就完成了
查看命令:bee
创建web项目-单体
new命令是新建一个Web项目,在命令行下执行bee new <项目名>
就可以创建一个新的项目
new这个命令生成的一般是前后端没分离的项目
命令:
go mod tidy
整理现有的依赖,使用此命令来下载特定的模块,并删除已经不用的模块
go mod download
下载go.mod
文件中指明的所有依赖,使用此命令来下载指定的模块
go run xxx.go
启动项目,访问项目
如果提示golang.org/x/sys/unix....//go:linkname must refer to declared function or variable
报错,在对应的项目下使用go get -u golang.org/x/sys
创建api项目-接口服务
上面的new命令是用来新建web项目,不过很多用户使用beego来开发API应用
所以这个bee api命令就是用来创建API应用的
和web项目相比,少了static和views目录
api命令一般用于生成前后端分离的项目
go mod tidy
整理现有的依赖,使用此命令来下载特定的模块,并删除已经不用的模块
go mod download
下载go.mod
文件中指明的所有依赖,使用此命令来下载指定的模块
go run xxx.go
启动项目,访问项目
generate命令
这个命令是用来自动化的生成代码的,包含了从数据库一键生成model,还包含了脚手架的,通过这个命令,让大家开发代码不再慢
例如:bee generate docs
bee generate docs
次命令含义:generate swagger doc file生产swagger文档文件
项目初始构建
构建项目
bee api quickstart
go mod tidy
bee generate docs
运行项目
在项目目录下使用bee run -gendoc=true -downdoc=true
运行项目。第一次运行时会自动下载调试工具swagger。
-gendoc=true表示每次自动化的build文档。当项目文件中controller或者routers目录下有变动时,就需要添加这一句
-downdoc=true会自动的下载swagger文档查看器。仅需要在第一次运行时使用,他会自动下载调试工具swagger
访问http://localhost:8080/swagger可以看到调试界面
MVC架构
什么是MVC:Model view Controller模型 视图 控制器
早期很多代码是混合在页面里面开发的, 比如php、java的jsp等,开发维护之分麻烦
架构:没有什么是加一层解决不了的
但是为了易于维护和使用作出以下规定:
- 控制层专注于处理请求以及控制试图跳转
- 视图专注于显示数据
- 模型,实体类与数据库一一映射处理底层逻辑
用户只访问视图,访问一个页面 点击跳转…跳到控制层
再加一层service,登录业务,注销业务,这些业务加到中间业务层返回数据给控制器,视图跳转到视图层,显示数据
Dao:操作数据库,Model:控制业务操作,保存数据修改数据查询数据
Model
- 业务处理:业务逻辑(Service)
- 数据持久层:CRUD(Dao)
View
- 展示数据
Controller
- 接受用户的请求(req:请求参数、Session信息)
- 交给业务层处理对应的代码
- 控制视图的跳转
- 登录-》接受用户的登录请求-》处理用户的请求(获取用户登录的参数,username,password)-》交给业务层处理登录业务(判断用户名密码是否正确)-》Dao层查询用户名和密码是否正确-》数据
路由
普通路由
RestFul 路由
自动注册路由
-
编写Controller
- struct必须是大写
- 方法也必须大写,不然访问不了
package controllers import "github.com/beego/beego/v2/server/web" // 定义好UserController // 结构和下面所有的方法都需要大写字母开头 // //localhost:8080/user type UserController struct { web.Controller } func (u *UserController) Hello() { u.Ctx.WriteString("user/hello") } func (u *UserController) Lgoin() { u.Ctx.WriteString("user/login") }
-
自动注册路由
package routers import ( beego "github.com/beego/beego/v2/server/web" "web-demo/controllers" ) func init() { //自动注册路由 beego.AutoRouter(&controllers.UserController{}) //首页路由 beego.Router("/", &controllers.MainController{}) }
手动路由
//手动路由
//beego.Get("/index", func(ctx *context.Context) {
//
//})
//beego.Post()
RestFul风格路由
//路由 /?:var
//Controller
//请求方式:请求的具体的方式;
beego.Router("/user/info/?:id", &controllers.UserController{}, "get:GetUserInfo")
处理请求参数
user.go
//localhost:8080/Register/username=yama&password=123456
func (u *UserController) Register() {
//1。获取前端请求参数
username := u.GetString("username")
password := u.GetString("password")
//2。调用具体的业务逻辑
if username == "" || password == "" {
u.Ctx.WriteString("注册失败")
}
u.Ctx.WriteString("注册成功。username=" + username)
}
表单对象传参
login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登录</title>
</head>
<body>
<form action="/user/login" method="post">
<p> 用户名:<input type="text" name="Username"></p>
<p> 密码:<input type="password" name="Password"></p>
<p><input type="submit" value="登录"></p>
</form>
</body>
</html>
router.go
beego.Router("/user/login", &controllers.UserController{}, "post:Login")
user.go
// 跳转到登录页
func (c *UserController) ToLogin() {
c.TplName = "login.html"
}
func (u *UserController) Login() {
type User struct {
Username string `form:"Username"`
Password string `form:"Username"`
}
postUser := User{}
u.BindForm(&postUser)
fmt.Println(postUser)
u.Ctx.WriteString(postUser.Username + ",登录成功")
}
错误处理
在做web开发的时候,经常需要页面跳转和错误处理
比如登录失败跳转到首页或者登录页
- 重定向
user.go
if postUser.Username != "admin" {
u.Redirect("/", 302)
}
- 404
router.go
//beego.ErrorHandler("404", func(writer http.ResponseWriter, request *http.Request) {
// t, _ := template.New("404.html").ParseFiles(beego.BConfig.WebConfig.ViewsPath + "/404.html")
// data := make(map[string]interface{})
// data["content"] = "page not found"
// t.Execute(writer, data)
//})
- controller
error.go
package controllers
import (
"github.com/beego/beego/v2/server/web"
)
type ErrorController struct {
web.Controller
}
func (c *ErrorController) Error404() {
c.Data["content"] = "page not found"
c.TplName = "404.html"
}
func (c *ErrorController) Error501() {
c.Data["content"] = "server error"
c.TplName = "501.html"
}
func (c *ErrorController) ErrorDb() {
c.Data["content"] = "database is now down"
c.TplName = "dberror.html"
}
router.go
beego.ErrorController(&controllers.ErrorController{})
Admin监控后台
默认Admin是关闭的,可以通过配置开启监控:
EnableAdmin = true
可以进行修改监听到地址和端口:
AdminAddr = "localhost"
AdminPort = 8088
session&cookie
会话
会话:用户打开一个浏览器,点击了很多超链接,访问多个web资源,关闭浏览器,这个过程可以称之为会话
有状态会话:一个通过来过教室,下次再来教室,我们就会知道这个同学,曾经来过,称之为有状态会话
保存会话的两种技术
cookie
- 客户端技术(响应,请求)
session
- 服务器技术,利用这个技术,可以保存用户的会话信息,我们可以把信息或者数据放在session中
user.go
// 统计页面访问次数
func (this *UserController) UserSession() {
//往服务器存放一个cookie,并且设置过期时间
//this.Ctx.SetCookie("name", "web cookie", 10)
//设置一个加密cookie
this.Ctx.SetSecureCookie("my-secret", "name", "web cookie")
this.Data["name"], _ = this.Ctx.GetSecureCookie("my-secret", "name")
v := this.GetSession("asta")
if v == nil {
this.SetSession("asta", int(1))
this.Data["num"] = 0
} else {
this.SetSession("asta", v.(int)+1)
this.Data["num"] = v.(int)
}
this.TplName = "index.tpl"
}
beegoORM
分层开发
model层 控制结构体与表映射关系,编写增删改查逻辑
service层调用model层查询数据,处理具体的业务逻辑
comtroller层接收用户请求,调用具体的service层处理,并响应回客户端
- 创建数据库
- Orm init 初始化数据库连接
- 结构体 - ORM - 数据库
- 执行同步
- CRUD
model/orm.go
package models
import (
// don't forget this
"github.com/beego/beego/v2/client/orm"
_ "github.com/go-sql-driver/mysql"
)
func init() {
//开启调试模式
orm.Debug = true
//同步结构体到表中
// need to register models in init
orm.RegisterModel(new(User))
//连接数据库
orm.RegisterDataBase("default", "mysql", "root:123456@tcp(127.0.0.1:3312)/beego?charset=utf8")
// automatically build table
orm.RunSyncdb("default", false, true)
}
model/user.go
package models
import (
"fmt"
"github.com/beego/beego/v2/client/orm"
"time"
)
type User struct {
// O 对象 R 关系 M 映射
ID int `orm:"column(id);auto"`
Name string `orm:"column(name)"`
Email string `orm:"column(email)"`
CreateTime time.Time `orm:"column(create_time);auto_now_add;type(datetime)"`
UpdateTime time.Time `orm:"column(update_time);auto_now;type(datetime)"`
}
// ORM CRUD
func UserInsert(user *User) int64 {
//创建orm对象
o := orm.NewOrm()
//插入
n, _ := o.Insert(user)
if n > 0 {
fmt.Println("数据插入成功!")
return n
}
return 0
}
controllers/user.go
func (this *UserController) AddUser() {
//模拟一个user数据
user := new(models.User)
user.Name = "yama"
user.Email = "231092380@qq.com"
//调用业务层来处理
n := models.UserInsert(user)
if n == 0 {
this.Ctx.WriteString("插入失败!")
} else {
this.Ctx.WriteString("插入成功!")
}
}
访问:http://localhost:8080/user/adduser 就会添加成功
定时任务
//创建定时任务 任务名字 定时 执行函数
tk1 := task.NewTask("tk1", "0/2 * * * * *", func(ctx context.Context) error {
fmt.Println("定时任务执行了")
return nil
})
//添加到任务列表中
task.AddTask("tk1", tk1)
//开始执行任务
task.StartTask()
defer task.StopTask()