1、介绍
beego是一个使用Go语言来开发WEB引用的GoWeb框架,该框架起始于2012年,由一位中国的程序员编写并进行公开,其目的就是为大家提供一个高效率的web应用开发框架。
1)特性
(1)简单化:RESTful支持,MVC模型;可以使用bee工具来提高开发效率,比如监控代码修改进行热编译,自动化测试代码,以及自动化打包部署等丰富的开发调试功能。
(2)智能化:beego框架封装了路由模块,支持智能路由,智能监控,并可以监控内存消耗,CPU使用以及goroutine的运行状况,方便开发者对线上应用进行监控分析。
(3)模块化:beego根据功能对代码进行节耦封装,形成了Session,Cache,Log,配置解析,性能监控,上下文操作,ORM等独立的模块,方便开发者进行使用。
(4)高性能:beego采用Go原生的http请求,goroutine的并发效率应付大流量的Web应用和API应用。
2)安装
(1)安装golang
1)wget -c https://storage.googleapis.com/golang/go1.18.2.linux-amd64.tar.gz
2)tar -zxvf go1.18.2.linux-amd64.tar.gz -C /usr/local
3)vim /etc/profile
在文件内容后面加上:
export PATH=$PATH:/usr/local/go/bin
export GOPATH=/home/goproject
4)source /etc/profile
(2)安装beego
export GOPROXY=https://goproxy.cn,direct
export GO111MODULE="on" or go env -w GO111MODULE=on
git config --global http.sslVerify false
开始安装
go install github.com/astaxie/beego/v2@latest
go install github.com/beego/bee/v2@latest
(3)配置
4)创建一个beego项目
package main
import (
beego "github.com/beego/beego/v2/server/web"
)
func main() {
beego.Run("localhost:8080")
}
编译:
go build -o hello hello.go
运行:
./hello
访问浏览器http://localhost:8080
2 Beego执行流程解读
Go语言执行的时候是main包下面的init函数、main函数依次执行。因此,先找到main.go文件。
首先,import导入了两个包,一个是routers,一个是beego。而在routers包前面,可以看到有一个“_”,这表明是引入routers包,并执行init方法。
首先到routers包下执行init方法:
router表示的是路由的意思,这个函数的功能是映射 URL 到 controller,第一个参数是 URL (用户请求的地址),这里注册的是 /,也就是访问的不带任何参数的 URL,第二个参数是对应的 Controller,即将把请求分发到那个控制器来执行相应的逻辑。
现在去MainController中去看一下有什么方法:
3 MVC框架学习
3.1 控制器controller
1)control基本使用
web.Controller 实现了接口 web.ControllerInterface,支持的函数如下:
可以通过 struct 重写,实现这些函数的自定义逻辑。
基本数据处理操作如下:
当然也可以不使用模版,直接用 this.Ctx.WriteString 输出字符串,如:
control定义完后,前段如何访问到这些control,得需要设置路由
2)路由router
在beego框架中,支持四种路由设置,他们分别是:基础路由,固定路由,正则路由和自动路由。
(1)先使用固定路由
package routers import ( beego "github.com/beego/beego/v2/server/web" "webtest/control" ) func init(){ beego.Router("/show",&control.ShowController{}) }
(2)基础路由
直接通过beego.Get,beego.POST,beego.Head,beego.Delete等方法来进行路由的映射。
GET路由 beego.GET("",func) beego.Get("/",func(ctx *context.Context){ ctx.Output.Body([]byte("hello world")) }) POST路由: beego.POST("",func)
(3)路由信息匹配(正则匹配)
Router(“/user/:username([\\w]+)”, &controllers.RController{})
this.Ctx.Input.Param(":username")
Router(“/download/*.*“, &controllers.RController{})
this.Ctx.Input.Param(":path")
this.Ctx.Input.Param(":ext")
Router(“/cms_:id([0-9]+).html”, &controllers.CmsController{})
匹配 cms_123.html 这样的 url :id = 123
(4)自定义路由
beego.Router("/show/info",&control.ShowController{},"get,post:ShowInfo") beego.Router("/show/info",&control.ShowController{},"get:ShowInfo;post:AddInfo")
(5)自动匹配
beego.AutoRouter(&controllers.ObjectController{})
通过反射获取该结构体中所有的实现方法:
/object/login 调用 ObjectController 中的 Login 方法
/object/logout 调用 ObjectController 中的 Logout 方法
除了前缀两个 /:controller/:method 的匹配之外,剩下的 url beego 会帮你自动化解析为参数,保存在 this.Ctx.Input.Params 当中:
/object/blog/2013/09/12 调用 ObjectController 中的 Blog 方法,参数如下:map[0:2013 1:09 2:12]
3)参数配置
beego 默认会解析当前应用下的 conf/app.conf 文件。 通过这个文件你可以初始化很多 beego 的默认参数:
appname = beepkg
httpaddr = "127.0.0.1"
httpport = 9090
runmode ="dev"
autorender = false
recoverpanic = false
viewspath = "myview"
你也可以在配置文件中配置应用需要用的一些配置信息,例如下面所示的数据库信息:
mysqluser = "root"
mysqlpass = "rootpass"
mysqlurls = "127.0.0.1"
mysqldb = "beego"
那么你就可以通过如下的方式获取设置的配置信息:
beego.AppConfig.String("mysqluser")
beego.AppConfig.String("mysqlpass")
beego.AppConfig.String("mysqlurls")
beego.AppConfig.String("mysqldb")
runmode 参数
runmode ="dev"
[dev]
httpport = 8080
[prod]
httpport = 8088
[test]
httpport = 8888
include参数
include "app2.conf"
3.2 数据层model
1) ORM 框架
已支持数据库驱动:
- MySQL:github.com/go-sql-driver/mysql
- PostgreSQL:github.com/lib/pq
- Sqlite3:github.com/mattn/go-sqlite3
(1)基本使用
//model/SQLInit/sql.go
import (
"github.com/beego/beego/v2/client/orm"
beego "github.com/beego/beego/v2/server/web"
)
type User struct{
Id int
Username string `orm:"size(40)"`
Password string `orm:"size(40)"`
Status int // 0 normal ;1 delete
}
func InitSQL(){
driverName,_ := beego.AppConfig.String("drivername")
// Database connect
user,_ := beego.AppConfig.String("mysqluser")
passwd,_ := beego.AppConfig.String("mysqlpass")
host,_ := beego.AppConfig.String("host")
port,_ := beego.AppConfig.String("port")
dbname,_ := beego.AppConfig.String("dbname")
conUrl := user + ":" + passwd + "@tcp(" + host + ":" + port + ")/" + dbname +"?charset=utf8&loc=Local"
orm.RegisterDataBase("default",driverName,conUrl)
orm.RegisterModel(new(User))
// create table
orm.RunSyncdb("default", false, true)
}
(2)具体使用
ORM 必须注册一个别名为 default 的数据库,作为默认使用。ORM 使用 golang 自己的连接池:
// 参数1 数据库的别名,用来在 ORM 中切换数据库使用
// 参数2 driverName
// 参数3 对应的链接字符串
orm.RegisterDataBase("default", "mysql", "root:root@/orm_test?charset=utf8")
// 参数4(可选) 设置最大空闲连接
// 参数5(可选) 设置最大数据库连接 (go >= 1.2)
maxIdle := 30
maxConn := 30
orm.RegisterDataBase("default", "mysql", "root:root@/orm_test?charset=utf8", maxIdle, maxConn)
然后进行注册,最佳设计是有单独的 models.go 文件,在他的 init 函数中进行注册。
import "github.com/beego/beego/v2/client/orm" type User struct { Id int Name string } func init(){ orm.RegisterModel(new(User)) }
其他注册模式
可以同时注册多个 model
orm.RegisterModel(new(User), new(School), new(Home))
使用表名前缀
orm.RegisterModelWithPrefix("prefix_", new(User))
(3)增删改查操作
区别原生sql查询。
已封装的几个方法 Read / Insert / Update / Delete / ReadOrCreate
o := orm.NewOrm()
user := new(User)
user.Name = "test" f
mt.Println(o.Insert(user))
其他封装的方法
先获取QuerySeter
// 获取 QuerySeter 对象,user 为表名
qs := o.QueryTable("user")
// 也可以直接使用 Model 结构体作为表名
qs = o.QueryTable(&User)
// 也可以直接使用对象作为表名
user := new(User)
qs = o.QueryTable(user) // 返回 QuerySete
QuerySeter进行处理
qs.Filter("id", 1) // WHERE id = 1
qs.Filter("profile__age", 18) // WHERE profile.age = 18
qs.Filter("profile__age__gt", 18) // WHERE profile.age > 18
qs.Filter("profile__age__gte", 18) // WHERE profile.age >= 18
gt / gte , lt / lte
qs.Filter("profile__age__in", 18, 20) // WHERE profile.age IN (18, 20)
qs.Filter("profile__age__in", 18, 20).Exclude("profile__lt", 1000)
// WHERE profile.age IN (18, 20) AND NOT profile_id < 1000
qs.Filter("name__iexact", "slene") // WHERE name LIKE 'slene'
qs.Filter("name__contains", "slene") // WHERE name LIKE BINARY '%slene%'
qs.Filter("name__icontains", "slene") // WHERE name LIKE '%slene%'
2)原生SQL查询
(1)创建一个RawSeter
func QueryPassByName(name string) string{
o := orm.NewOrm()
sql := "select * from user where username = '" + name +"'"
util.Info("[sql] - " + sql)
//创建一个RawSeter
res := o.Raw(sql)
}
RawSeter接口中所包含的方法:
type RawSeter interface {
Exec() (sql.Result, error)
QueryRow(…interface{}) error
QueryRows(…interface{}) (int64, error)
SetArgs(…interface{}) RawSeter
Values(*[]Params, …string) (int64, error)
ValuesList(*[]ParamsList, …string) (int64, error)
ValuesFlat(*ParamsList, string) (int64, error)
RowsToMap(*Params, string, string) (int64, error)
RowsToStruct(interface{}, string, string) (int64, error)
Prepare() (RawPreparer, error)
}
(2)QueryRows方法提供高级sql mapper功能
func QueryPassByName(name string) string{
o := orm.NewOrm()
sql := "select * from user where username = '" + name +"'"
util.Info("[sql] - " + sql)
//创建一个RawSeter
res := o.Raw(sql)
var users []SQLInit.User
//QueryRows查询
num, err := res.QueryRows(&users)
if err == nil && num > 0 {
return users[num-1].Password
}else {
return ""
}
}
安全起见,可以这样写
o := orm.NewOrm()
var r RawSeter
r = o.Raw("select * from user where username = ?", name)
(3)Values方法返回结果集的 key => value 值
func QueryAllInfoById(id string) []orm.Params{
o := orm.NewOrm()
sql := "select * from user where id = " + id
util.Info("[sql] - " + sql)
res := o.Raw(sql)
var maps []orm.Params
num, err := res.Values(&maps)
if err == nil && num > 0 {
return maps
}else {
return nil
}
}
(3)RowsToMap方法查询结果匹配到 map 里
res := make(orm.Params)
nums, err := o.Raw("SELECT name, value FROM options_table").RowsToMap(&res, "name", "value")
(4)Exec方法返回 sql.Result 对象
res, err := o.Raw("UPDATE user SET name = ?", "your").Exec()
if err == nil {
num, _ := res.RowsAffected()
fmt.Println("mysql row affected nums: ", num)
}
3.3 视图层VIEW
模板语法
go 统一使用了 {{ 和 }} 作为左右标签
使用 . 来访问当前位置的上下文
使用 $ 来引用当前模板根级的上下文
使用 $var 来访问创建的变量