beego 框架使用

beego 框架相对于仅包含路由和控制器核心模块的 echo 框架、gin 框架更为完备,beego 是一个完整的 MVC 框架,它包括 controller(路由和控制器)、model(数据库ORM 封装)以及 view (模板和标签)等 MVC 必备模块。

使用 beego 开发 go 语言项目,需要编写控制器 controller、业务模型 model 以及 view (html 模板)等模块。

 

1. 控制器 controller

我们看下 beego 控制器如何编写。

我们在 beego 项目 codebaoku 的子目录 controllers 下,编写第一个文件: codebaoku/controllers/default.go。

import (
    "github.com/astaxie/beego"
)

// 定义一个控制器结构体
// 我们一般一个模块定义一个控制器
type MainController struct {
    // 嵌套 beego 基础控制器,在 go 语言中嵌套 struct,类似继承的概念。
    // 这里就相当于,继承了 beego.Controller 的方法和属性。
	beego.Controller 
}

// 覆盖beego.Controller的Get方法,用于处理 RESTful 请求中的 get 请求
// beego.Controller 默认支持多种 RESTful方法,例如:Post、Put、Delete等
func (c *MainController) Get() {
    // Data是继承过来的属性,是 map 类型,可以保存任意类型数据,主要用于保存请求响应数据
    // 我们可以通过 Data 将参数,传入视图模板文件。
	// 这里设置了两个参数
	c.Data["Website"] = "codebaoku.com"
	c.Data["Email"] = "go@codebaoku.com"
	
	// 设置需要渲染的模板文件,框架会去 views 目录查找这个模板文件
	c.TplName = "index.tpl"
}

 

2. 设置路由 Url

我们看下 beego 如何设置路由。

我们在 beego 项目 codebaoku 的子目录 routers 下,编写文件: codebaoku/routers/router.go。

package routers

import (
    "codebaoku/controllers"
    "github.com/astaxie/beego"
)

// go 包初始化函数,go 语言中在导入一个包的时候,如果被导入包存在 init 函数,会执行 init 函数
// 因此这里可以使用 init 函数初始化路由设置

func init() {
    // 使用 beego.Router 函数,注册路由规则。
    // 第一个参数是url路由,第二个参数是控制器
    // 这里的意思就是将访问 / 这个url的请求,交给controllers.MainController控制器处理。
    beego.Router("/", &controllers.MainController{})
}

如果我们增加一个路由设置:

beego.Router("/codebaoku", &controllers.MainController{})

router.go的代码如下:

package routers

import (
    "codebaoku/controllers"
    "github.com/astaxie/beego"
)

func init() {
    beego.Router("/", &controllers.MainController{})
    beego.Router("/codebaoku", &controllers.MainController{})
}

再次运行 codebaoku 项目,我们访问:http://localhost:8080/codebaoku 和 http://localhost:8080/ 得到的结果一样,因为这两个 Url 地址都是由同一个控制器处理。

路由规则说明:
大家可能发现上面的路由注册规则,只是定义了Url 由哪个控制器执行,但是没有说明 Url 请求由控制器的那个函数执行,一个控制器可以包含多个函数。

beego RESTful路由规则,默认是通过 请求方法 确认由那个控制器方法执行,例如:get请求,由 Get 方法执行,POST请求由 Post 方法执行。

 

3. 编写 model 业务逻辑

这里我们看一个 mysql 数据库操作的例子。

1) 定义表结构

CREATE TABLE `users` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增ID',
  `username` varchar(30) NOT NULL COMMENT '账号',
  `password` varchar(100) NOT NULL COMMENT '密码',
   PRIMARY KEY (`id`)
  ) ENGINE=InnoDB DEFAULT CHARSET=utf8

大家可以使用自己熟悉的工具将 mysql 表创建好。

2) 初始化数据库连接

一般初始化数据库连接都是在 main.go 入口的地方设置一次就行,下面看下 main.go 文件改成什么样。

package main

import (
    _ "codebaoku/routers"

    "github.com/astaxie/beego"
    "github.com/astaxie/beego/orm"
    _ "github.com/go-sql-driver/mysql"
)

func init() {
    // 这里注册一个default默认数据库,数据库驱动是mysql.
    // 第三个参数是数据库dsn, 配置数据库的账号密码,数据库名等参数
    //  dsn参数说明:
    //      username    - mysql账号
    //      password    - mysql密码
    //      db_name     - 数据库名
    //      127.0.0.1:3306 - 数据库的地址和端口
    orm.RegisterDataBase("default", "mysql", "username:password@tcp(127.0.0.1:3306)/db_name?charset=utf8")
}

func main() {
    beego.Run()
}

为了初始化 mysql 连接,在入口 main.go 文件,增加 init 函数初始化数据库设置。

3) 创建model

然后创建一个 user model, 文件路径:codebaoku/models/user.go, 代码如下:

package models

import (
	"github.com/astaxie/beego/orm"
)

// 定义User模型,绑定users表结构, 其实就是用来保存sql查询结果。
type User struct {
	Id int
	Username string
	Password string
}

// 定义User 模型绑定那个表?
func (u *User) TableName() string {
    // 返回mysql表名
	return "users"
}

//初始化函数,可以用来向orm注册model
func init() {
    // 向orm注册user模型
	orm.RegisterModel(&User{})
}

// 根据id查询用户信息
func GetUserById(id int) *User {
	if  id == 0 {
		return  nil
	}
    
    // 创建orm对象, 后面都是通过orm对象操作数据库
	o := orm.NewOrm()
	
	// 初始化一个User模型对象
	user := User{}
	// 设置查询参数
	user.Id = id
	
	// 调用Read方法,根据user设置的参数,查询一条记录,结果保存到user结构体变量中
	// 默认是根据主键进行查询
	// 等价sql: SELECT `id`, `username`, `password` FROM `users` WHERE `id` = 1
	err := o.Read(&user)
	
	// 检测查询结果,
	if err == orm.ErrNoRows {
		// 找不到记录
		return nil
	} else if err == orm.ErrMissPK {
		// 找不到住建
		return nil
	}
	
	return &user
}

4) 通过控制器调用 model

下面修改控制器代码
文件: codebaoku/controllers/default.go

func (c *MainController) Get() {
	c.Data["Website"] = "codebaoku.com"
	c.Data["Email"] = "go@codebaoku.com"
	
	// 调用model,查询用户id为1 的用户信息
    user := models.GetUserById(1)
	
	// 然后将user数据保存到Data中, 将参数传给后面的 views 视图模板处理
	c.Data["user"] = user
	
	// 使用新的视图模板user.tpl
	c.TplName = "user.tpl"
}

 

4. 编写 view 视图

我们编写一个新的视图模板,文件为 codebaoku/views/user.tpl。

<!DOCTYPE html>
<html lang="zh-CN">
<head>
	<title>Demo</title>
	<meta charset="utf-8">
</head>
<body>
<h1>网站: {{.Website}}</h1>
{{ if .user }}
用户名: {{.user.Username}}
{{else}}
查找不到用户
{{ end }}
</body>
</html>

访问 http://localhost:8080, 如果查询的用户存在,则显示用户名,否则显示查找不到用户。

提示: beego使用的是go自带的模板引擎,如果暂时看不懂,大家可以先忽略具体的模板语法,后续的教程会有讲解。

 

5. 项目打包

项目完成后需要将代码打包发布到线上,这里依然推荐使用 bee 工具打包,bee 工具可以一键将项目需要的相关文件一起打包成一个压缩包,只需要到线上解压即可。

下面是 bee 打包的例子, 首先将命令窗口的目录切换到项目根目录 codebaoku, 然后执行下面命令:

bee pack

打包成功后再项目根目录下生成一个 codebaoku.tar.gz 的压缩包,命名格式: ${项目名}.tar.gz

我们可以解压缩,看看压缩包包含什么内容:

codebaoku.tar.gz
├── conf            - 配置文件存放目录,这里包含我们的配置文件
├── static          - 静态资源目录,包含我们静态资源文件
├── views           - 视图模板目录,包含模板文件
└── codebaoku         - 这个就是我们的项目打包后的可执行程序,按我们项目命名

注意: 线上服务器一般都是 linux 环境,所以建议在 linux 环境打包项目,不要在 windows 环境打包,否则打包生成的可执行程序是 .exe 格式的,linux 无法运行。

我们也可以手动编译项目,然后将相关文件打包到一块。

beego 默认使用了 INI 格式解析配置文件,通常在项目中会存在很多系统参数、业务参数配置,这些参数通常都是通过配置文件进行配置,而且不是写死在代码里面。修改配置文件后,需要重启应用,配置才生效,即使使用bee run运行项目也得重启。