beego框架的mvc
beego框架是一款典型的MVC框架,执行逻辑如下:
本图来自beego官网,具体的说明可以点击 这里查看具体说明。
创建一个项目
为了更好的进行说明,下面将通过bee工具创建一个beego的项目,如无特殊说明,后续的内容都会以这个测试项目为基础。
$PATH/src
bee new mytest
执行结果如下:
项目创建好之后的目录结构如下:
confcontrollersmodelsroutersstatictestsviewsmain.go
项目的运行
$GOPATH/src/mytest
bee run
localhost:8080
router 路由
基础RESTful 路由
main.go
package main
import (
_ "mytest/routers"
"github.com/astaxie/beego"
)
func main() {
beego.Run()
}
importroutersrouters
routers/router.go
package routers
import (
"mytest/controllers"
"github.com/astaxie/beego"
)
func init() {
beego.Router("/", &controllers.MainController{})
}
beego.Router
首先,我们先来简单的做一个路由测试,如下:
routers/router.go
package routers
import (
"mytest/controllers"
"github.com/astaxie/beego"
)
func init() {
beego.Router("/", &controllers.MainController{})
beego.Router("/mytest", &controllers.MyTestController{})
}
controllers/default.go
package controllers
import (
"github.com/astaxie/beego"
)
type MainController struct {
beego.Controller
}
// 新创建一个controller
type MyTestController struct {
beego.Controller
}
func (c *MainController) Get() {
c.Data["Website"] = "beego.me"
c.Data["Email"] = "astaxie@gmail.com"
c.TplName = "index.tpl"
}
// 重写get方法
func (c *MyTestController) Get() {
c.Ctx.WriteString("hello,this is myTest")
}
/mytestlocalhost:8080/mytest
controllers/default.goMyTestController/mytest
在beego中,内置支持的基础函数如下:
- 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)
我们在使用的时候,可以根据需要进行函数的重写,例如,上面的代码中,我们基于MyTestController控制器上重写了GET方法。
localhost:8080/mytest
正则路由
beego为了更加方便的进行路由设置,支持多种方式的路由写法,具体情况如下:
下面针对不同的路由写法逐一的进行说明。
beego.Router(“/api/?:id”, &controllers.RController{})
默认匹配 //例如对于URL”/api/123”可以匹配成功,此时变量”:id”值为”123”
例如:
routers/router.go
package routers
import (
"mytest/controllers"
"github.com/astaxie/beego"
)
func init() {
beego.Router("/", &controllers.MainController{})
beego.Router("/mytest", &controllers.MyTestController{})
beego.Router("/router/?:id", &controllers.MyRouterController{})
}
controllers/default.go
package controllers
import (
"github.com/astaxie/beego"
)
type MainController struct {
beego.Controller
}
// 新创建一个controller
type MyTestController struct {
beego.Controller
}
type MyRouterController struct {
beego.Controller
}
func (c *MainController) Get() {
c.Data["Website"] = "beego.me"
c.Data["Email"] = "astaxie@gmail.com"
c.TplName = "index.tpl"
}
// 重写get方法
func (c *MyTestController) Get() {
c.Ctx.WriteString("hello,this is myTest")
}
func (m *MyRouterController) Get() {
// 获取传递过来的数据
ids := m.Ctx.Input.Param(":id")
// 将传递过来的数据映射到网页当中
m.Ctx.WriteString(ids)
}
localhost:8080/router/123
如果我们将路由更改为如下内容,匹配的结果将会发生变化:
func init() {
beego.Router("/", &controllers.MainController{})
beego.Router("/mytest", &controllers.MyTestController{})
// beego.Router("/router/?:id", &controllers.MyRouterController{})
beego.Router("/router/:id", &controllers.MyRouterController{})
}
?:idlocalhost:8080/router/123
?
如果说希望匹配具体的数字,也可以通过正则进行修饰,如下:
beego.Router(“/api/:id([0-9]+)“, &controllers.RController{})
自定义正则匹配 //例如对于URL”/api/123”可以匹配成功,此时变量”:id”值为”123”。
如果需要匹配字符串,可以使用类似于下面的路由进行设置:
beego.Router(“/user/:username([\w]+)“, &controllers.RController{})
正则字符串匹配 //例如对于URL”/user/astaxie”可以匹配成功,此时变量”:username”值为”astaxie”.
如果需要匹配请求地址当中的文件名和文件后缀,路由可以进行类似如下的设置:
beego.Router(“/download/*.*”, &controllers.RController{})
例如:
routers/router.go
package routers
import (
"mytest/controllers"
"github.com/astaxie/beego"
)
func init() {
beego.Router("/", &controllers.MainController{})
beego.Router("/mytest", &controllers.MyTestController{})
// beego.Router("/router/?:id", &controllers.MyRouterController{})
beego.Router("/router/:id", &controllers.MyRouterController{})
beego.Router("/router/*.*", &controllers.MyRouterFileController{})
}
controllers/default.go
package controllers
import (
"github.com/astaxie/beego"
)
type MainController struct {
beego.Controller
}
// 新创建一个controller
type MyTestController struct {
beego.Controller
}
type MyRouterController struct {
beego.Controller
}
type MyRouterFileController struct {
beego.Controller
}
func (c *MainController) Get() {
c.Data["Website"] = "beego.me"
c.Data["Email"] = "astaxie@gmail.com"
c.TplName = "index.tpl"
}
// 重写get方法
func (c *MyTestController) Get() {
c.Ctx.WriteString("hello,this is myTest")
}
func (m *MyRouterController) Get() {
// 获取传递过来的数据
ids := m.Ctx.Input.Param(":id")
m.Ctx.WriteString(ids)
}
func (m *MyRouterFileController) Get() {
// 获取文件名 :path
paths := m.Ctx.Input.Param(":path")
// 获取文件名后缀 :ext
exts := m.Ctx.Input.Param(":ext")
m.Ctx.WriteString(paths)
m.Ctx.WriteString(exts)
}
localhost:8080/router/my.xml
如果需要一次性匹配完整的文件,可以如下:
beego.Router(“/download/ceshi/*“, &controllers.RController{})
例如,我们可以直接将上面的路由改为如下:
beego.Router("/router/*", &controllers.MyRouterFileController{})
控制器的Get方法改为如下:
func (m *MyRouterFileController) Get() {
// 获取文件名 :path
// paths := m.Ctx.Input.Param(":path")
// // 获取文件名后缀 :ext
// exts := m.Ctx.Input.Param(":ext")
// m.Ctx.WriteString(paths)
splats := m.Ctx.Input.Param(":splat")
m.Ctx.WriteString(splats)
}
localhost:8080/router/my.json
:int
例如:
beego.Router(“/:id:int”, &controllers.RController{})
:string
例如:
beego.Router(“/:hi:string”, &controllers.RController{})
this.Ctx.Input.Param(":id")
this.Ctx.Input.Param(":username")
this.Ctx.Input.Param(":splat")
this.Ctx.Input.Param(":path")
this.Ctx.Input.Param("::ext")
自定义方法
GETGetPOSTPost
beego.Router("/",&IndexController{},"*:Index")
第一个参数为路由,第二个参数是控制器,第三个参数是用来设置路由请求对应的method,定义如下:
*;,
例如,
routers/router.go
beego.Router("/router/hello", &controllers.MyRouterHelloController{}, "get:HelloFunc")
通过第三个参数来重写get方法。
controllers/default.go
type MyRouterHelloController struct {
beego.Controller
}
func (m *MyRouterHelloController) HelloFunc() {
m.Ctx.WriteString("hello,world")
}
localhost:8080/router/hello
可用的http method:
- *: 包含以下所有的函数
- get: GET 请求
- post: POST 请求
- put: PUT 请求
- delete: DELETE 请求
- patch: PATCH 请求
- options: OPTIONS 请求
- head: HEAD 请求
如果同时存在 * 和对应的 HTTP Method,那么优先执行 HTTP Method 的方法,例如同时注册了如下所示的路由:
beego.Router("/simple",&SimpleController{},"*:AllFunc;post:PostFunc")
POSTPostFuncAllFunc
上面说明了beego框架中常用的路由写法,具体的内容可以参照官网文档进行学习。
操作数据库
在beego框架中,既可以通过sql语句来实现对数据库的操作,也可以通过orm来实现对数据库的操作。下面来进行具体的说明。
通过sql语句操作数据库
beego当中支持通过sql语句来操作数据库。但是在使用之前,需要先通过go get命令安装mysql的驱动。
go get -u github.com/go-sql-driver/mysql
具体的应用如下:
routers/router.go
package routers
import (
"mytest/controllers"
"github.com/astaxie/beego"
)
func init() {
beego.Router("/", &controllers.MainController{})
beego.Router("/mytest", &controllers.MyTestController{})
// beego.Router("/router/?:id", &controllers.MyRouterController{})
beego.Router("/router/:id", &controllers.MyRouterController{})
// beego.Router("/router/*.*", &controllers.MyRouterFileController{})
beego.Router("/router/*", &controllers.MyRouterFileController{})
beego.Router("/router/hello", &controllers.MyRouterHelloController{}, "get:HelloFunc")
// 设置sql操作的路由
beego.Router("/mysql/sql", &controllers.MySqlTestSqlController{}, "get:SqlFunc")
}
controllers/mysqltest.go
package controllers
import (
"database/sql"
"github.com/astaxie/beego"
_ "github.com/go-sql-driver/mysql"
)
type MySqlTestSqlController struct {
beego.Controller
}
const (
db = "mysql"
user = "root"
pass = "123456"
host = "127.0.0.1"
port = "3306"
char = "charset=utf8"
data = "learngo1"
)
func (this *MySqlTestSqlController) SqlFunc() {
//创建一个数据表
// 第一步,链接数据库
params := user + ":" + pass + "@tcp(" + host + ":" + port + ")/" + data + "?" + char
// 1. 打开数据库
conn, err := sql.Open(db, params)
if err != nil {
beego.Error("数据库链接错误:", err)
return
}
// 2. 通过defer关闭数据库
defer conn.Close()
// 第二步,操作数据库
// 1. 设置sql语句
create_sql := `CREATE TABLE mytest1 ( userid INT PRIMARY KEY AUTO_INCREMENT, username varchar(255) NOT NULL ) ENGINE = InnoDB CHARSET = utf8;`
// 2. 执行sql语句
_, err2 := conn.Exec(create_sql)
if err2 != nil {
beego.Error("执行sql错误:", err2)
return
}
this.Ctx.WriteString("创建数据表成功")
}
localhost:8080/mysql/sql
Exec
routers/router.go
package routers
import (
"mytest/controllers"
"github.com/astaxie/beego"
)
func init() {
beego.Router("/", &controllers.MainController{})
beego.Router("/mytest", &controllers.MyTestController{})
// beego.Router("/router/?:id", &controllers.MyRouterController{})
beego.Router("/router/:id", &controllers.MyRouterController{})
// beego.Router("/router/*.*", &controllers.MyRouterFileController{})
beego.Router("/router/*", &controllers.MyRouterFileController{})
beego.Router("/router/hello", &controllers.MyRouterHelloController{}, "get:HelloFunc")
// 设置sql操作的路由
beego.Router("/mysql/sql", &controllers.MySqlTestSqlController{}, "get:SqlFunc")
// 通过sql语句实现增删改操作
beego.Router("/mysql/insert", &controllers.MySqlTestSqlController{}, "get:InsertFunc")
beego.Router("/mysql/update", &controllers.MySqlTestSqlController{}, "get:UpdateFunc")
beego.Router("/mysql/del", &controllers.MySqlTestSqlController{}, "get:DelFunc")
beego.Router("/mysql/search", &controllers.MySqlTestSqlController{}, "get:SearchFunc")
}
controllers/mytestsql.go
package controllers
import (
"database/sql"
"github.com/astaxie/beego"
_ "github.com/go-sql-driver/mysql"
)
type MySqlTestSqlController struct {
beego.Controller
}
type users struct {
userid int
username string
}
const (
db = "mysql"
user = "root"
pass = "123456"
host = "127.0.0.1"
port = "3306"
char = "charset=utf8"
data = "learngo1"
)
func (this *MySqlTestSqlController) SqlFunc() {
//创建一个数据表
// 第一步,链接数据库
params := user + ":" + pass + "@tcp(" + host + ":" + port + ")/" + data + "?" + char
// 1. 打开数据库
conn, err := sql.Open(db, params)
if err != nil {
beego.Error("数据库链接错误:", err)
return
}
// 通过defer关闭数据库
defer conn.Close()
// 第二步,操作数据库
// 1. 设置sql语句
create_sql := `CREATE TABLE mytest1 ( userid INT PRIMARY KEY AUTO_INCREMENT, username varchar(255) NOT NULL ) ENGINE = InnoDB CHARSET = utf8;`
// 2. 执行sql语句
_, err2 := conn.Exec(create_sql)
if err2 != nil {
beego.Error("执行sql错误:", err2)
return
}
this.Ctx.WriteString("创建数据表成功")
}
func (this *MySqlTestSqlController) InsertFunc() {
params := user + ":" + pass + "@tcp(" + host + ":" + port + ")/" + data + "?" + char
conn, err := sql.Open(db, params)
if err != nil {
beego.Error("数据库链接错误:", err)
return
}
defer conn.Close()
// 设置sql语句
sql := `insert into mytest1(username) values("张三")`
// 执行sql语句
_, err = conn.Exec(sql)
if err != nil {
beego.Error("插入数据错误:", err)
return
}
this.Ctx.WriteString("插入数据成功")
}
func (this *MySqlTestSqlController) UpdateFunc() {
params := user + ":" + pass + "@tcp(" + host + ":" + port + ")/" + data + "?" + char
conn, err := sql.Open(db, params)
if err != nil {
beego.Error("数据库链接错误:", err)
return
}
defer conn.Close()
// 设置sql语句
sql := `update mytest1 set username = "晓晓" where userid = 1`
// 执行sql语句
_, err = conn.Exec(sql)
if err != nil {
beego.Error("更改数据错误:", err)
return
}
this.Ctx.WriteString("更改数据成功")
}
func (this *MySqlTestSqlController) DelFunc() {
params := user + ":" + pass + "@tcp(" + host + ":" + port + ")/" + data + "?" + char
conn, err := sql.Open(db, params)
if err != nil {
beego.Error("数据库链接错误:", err)
return
}
defer conn.Close()
// 设置sql语句
sql := `delete from mytest1 where userid = 1`
// 执行sql语句
_, err = conn.Exec(sql)
if err != nil {
beego.Error("删除数据错误:", err)
return
}
this.Ctx.WriteString("删除数据成功")
}
func (this *MySqlTestSqlController) SearchFunc() {
params := user + ":" + pass + "@tcp(" + host + ":" + port + ")/" + data + "?" + char
conn, err := sql.Open(db, params)
if err != nil {
beego.Error("数据库链接错误:", err)
return
}
defer conn.Close()
// 设置sql语句
sql := `select * from mytest1`
// 执行sql语句
//
res, errSearch := conn.Query(sql)
if errSearch != nil {
beego.Error("查询数据错误:", errSearch)
return
}
var u users
// 打印查询结果
for res.Next() {
res.Scan(&u.userid, &u.username)
beego.Info("id:", u.userid, ",name:", u.username)
}
this.Ctx.WriteString("查询数据成功")
}
在上面的代码中,我们在增删改的操作中使用了Exec()函数,在查询的过程中使用了Query函数,但是除了这些函数以外,还有其他的函数,可以点击 这里查看。
使用ORM操作数据库
首先,在使用orm之前还是需要通过go get命令下载orm。
go get github.com/astaxie/beego/orm
安装完成之后就可以使用orm来进行数据库的增删改查操作。
orm的使用需要通过创建一个结构体与数据表进行相对应。例如数据表的结构如下:
我们需要创建一个结构体与数据表对应,如下:
type Mytest1 struct {
Userid int
Username string
}
同时,想要使用orm,需要对数据库进行初始化的设置,我们可以把这些初始化设置放在models模块里面的model.go中的init函数中。
func init() {
// 链接数据库
orm.RegisterDataBase("default", "mysql", "root:123456@tcp(127.0.0.1:3306)/learngo1?charset=utf8")
// 注册表
orm.RegisterModel(new(Mytest1))
// 生成表 false 为禁止强制更新 true为强制更新 第三个参数是是否查看创建表的过程
orm.RunSyncdb("default", false, true)
}
这样方便在controller中通过orm操作数据库。
上面的步骤设置完成之后,可以在main.go的入口文件当中引入。
package main
import (
_ "mytest/models"
_ "mytest/routers"
"github.com/astaxie/beego"
)
func main() {
beego.Run()
}
当我们在将上面的基础代码写完之后,就可以通过orm进行操作数据库啦。
完整示例如下:
routers/router.go
package routers
import (
"mytest/controllers"
"github.com/astaxie/beego"
)
func init() {
beego.Router("/", &controllers.MainController{})
beego.Router("/mytest", &controllers.MyTestController{})
// beego.Router("/router/?:id", &controllers.MyRouterController{})
beego.Router("/router/:id", &controllers.MyRouterController{})
// beego.Router("/router/*.*", &controllers.MyRouterFileController{})
beego.Router("/router/*", &controllers.MyRouterFileController{})
beego.Router("/router/hello", &controllers.MyRouterHelloController{}, "get:HelloFunc")
// 设置sql操作的路由
beego.Router("/mysql/sql", &controllers.MySqlTestSqlController{}, "get:SqlFunc")
// 通过sql语句实现增删改操作
beego.Router("/mysql/insert", &controllers.MySqlTestSqlController{}, "get:InsertFunc")
beego.Router("/mysql/update", &controllers.MySqlTestSqlController{}, "get:UpdateFunc")
beego.Router("/mysql/del", &controllers.MySqlTestSqlController{}, "get:DelFunc")
beego.Router("/mysql/search", &controllers.MySqlTestSqlController{}, "get:SearchFunc")
// 设置orm操作的路由
beego.Router("/mysql/orm/insert", &controllers.MysqlTestOrmController{}, "get:OrmInsertFunc")
beego.Router("/mysql/orm/update", &controllers.MysqlTestOrmController{}, "get:OrmUpdateFunc")
beego.Router("/mysql/orm/del", &controllers.MysqlTestOrmController{}, "get:OrmDelFunc")
beego.Router("/mysql/orm/search", &controllers.MysqlTestOrmController{}, "get:OrmSearchFunc")
}
controllers/mytestorm.go
package controllers
import (
"mytest/models"
"github.com/astaxie/beego"
"github.com/astaxie/beego/orm"
_ "github.com/go-sql-driver/mysql"
)
type MysqlTestOrmController struct {
beego.Controller
}
func (this *MysqlTestOrmController) OrmInsertFunc() {
o := orm.NewOrm()
o.Using("default")
stu := models.Mytest1{}
stu.Username = "张三丰"
_, err := o.Insert(&stu)
if err != nil {
beego.Error("添加错误:", err)
return
}
this.Ctx.WriteString("添加成功")
}
func (this *MysqlTestOrmController) OrmUpdateFunc() {
// 获取orm对象
o := orm.NewOrm()
// 获取更新对象
stu := models.Mytest1{Userid: 2}
// 查询对象
err := o.Read(&stu)
if err != nil {
beego.Error("查询数据错误:", err)
return
}
// 给查询到的对象进行重新赋值
stu.Username = "hello先生"
// 进行更新操作
_, err = o.Update(&stu)
if err != nil {
beego.Error("更新失败:", err)
return
}
this.Ctx.WriteString("更新成功")
}
func (this *MysqlTestOrmController) OrmDelFunc() {
// 获取orm对象
o := orm.NewOrm()
// 获取删除对象
stu := models.Mytest1{Userid: 2}
// 通过方法进行删除
_, err := o.Delete(&stu)
if err != nil {
beego.Error("删除失败:", err)
return
}
this.Ctx.WriteString("删除成功")
}
func (this *MysqlTestOrmController) OrmSearchFunc() {
x := orm.NewOrm()
x.Using("default")
stu := models.Mytest1{Userid: 3}
err := x.Read(&stu)
if err != nil {
beego.Error("查询失败:", err)
return
}
beego.Info(stu.Username)
this.Ctx.WriteString("查询成功")
}