beego入门笔记

Beego Learn Note

示例环境在Deepin系统下。

deepin 15.9.3
├── Beego     : 1.11.2
├── GoVersion : go1.12.4
├── GOOS      : linux
├── GOARCH    : amd64
├── NumCPU    : 1
├── GOPATH    : /home/jehorn/workspace/go
├── GOROOT    : /usr/local/go
├── Compiler  : gc
└── Date      : Saturday, 27 Apr 2019

Linux下配置Go开发环境

首先从Go官网下载对应的压缩包。
下载完毕后解压,然后移动至/usr/local下:

sudo mv go /usr/local/

然后配置环境变量:

sudo vim /etc/profile

在结尾添加(其中GOPATH请替换自己的路径):

export GOROOT=/usr/local/go
export GOARCH=amd64
export GOOS=linux
export GOPATH=/home/jehorn/workspace/go
export GOBIN=$GOROOT/bin
export PATH=$GOPATH/bin:$GOROOT/bin:$PATH
export PATH=$GOPATH/bin:$PATH

然后执行

source /etc/profile

控制台输出go version有版本号输出即配置完成。


安装beego:

GOPATH目录下,执行:

go get github.com/astaxie/beego
go get github.com/beego/bee

执行bee version看到版本号即安装成功。


执行bee new demo,即可新建一个项目:

jehorn@jehorn-PC:~/workspace/go/src/demo$ tree
.
├── conf
│   └── app.conf
├── controllers
│   └── default.go
├── main.go
├── models
├── routers
│   └── router.go
├── static
│   ├── css
│   ├── img
│   └── js
│       └── reload.min.js
├── tests
│   └── default_test.go
└── views
    └── index.tpl

10 directories, 7 files

Linux下IDE配置

安装VSCode

然后安装go插件。

然后打开File-preferences-settings,在右上角点开扩展菜单,选择Open settings.json,然后在右侧的USER SETTINGS中输入:

    "go.buildOnSave": "workspace",
    "go.lintOnSave": "package",
    "go.vetOnSave": "package",
    "go.buildTags": "",
    "go.buildFlags": [],
    "go.lintFlags": [],
    "go.vetFlags": [],
    "go.coverOnSave": false,
    "go.useCodeSnippetsOnFunctionSuggest": false,
    "go.formatOnSave": true,
    "go.formatTool": "goreturns",
    "go.goroot": "/usr/local/go",
    "go.gopath": "/home/jehorn/workspace/go"

保存,然后就可以打开项目。
项目打开以后,可能会有一些包提示你安装,直接点击install即可。

beego项目运行原理

$GOPATH/src/demo/目录下,命令行运行bee run,然后打开浏览器localhost:8080可以看到运行的beego项目。

ServerBrowserServerBrowserhttp:localhost:8080Main.gorouter.Init()Controller.Get()Viewindex.tpl

ORM

ORM创建

Object Relation Mapping(对象关系映射)。

通过结构体对象来操作对应的数据库表。
可以生成结构体相对应的数据库表。

安装:

go get github.com/astaxie/beego/orm

安装完成之后,在models文件夹新建一个实体 user.go

package models

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

type User struct {
    Id int
    Name string
    Pwd string
}

func init() {
    // 链接数据库
    orm.RegisterDataBase("default", "mysql", "root:123456@tcp(127.0.0.1:3306)/demo?charset=utf8")
    // 映射model数据(new(Type)...)
    orm.RegisterModel(new(User))
    // 生成表(别名, 是否强制更新, 是否可见)
    orm.RunSyncdb("default", false, true)
}

然后在main.go中调用init()方法:

package main

import (
    _ "demo/models"
    ...
)

...

最后在执行bee run之前,先在mysql中创建一个数据库:

create database demo;
-- Query OK, 1 row affected (0.02 sec)

执行bee run:

C:\Users\Jehorn\Work\projects\Go\src\demo>bee run
______
| ___ \
| |_/ /  ___   ___
| ___ \ / _ \ / _ \
| |_/ /|  __/|  __/
\____/  \___| \___| v1.10.0
2019/05/05 15:49:24 INFO     ▶ 0001 Using 'demo' as 'appname'
2019/05/05 15:49:24 INFO     ▶ 0002 Initializing watcher...
2019/05/05 15:49:27 SUCCESS  ▶ 0003 Built Successfully!
2019/05/05 15:49:27 INFO     ▶ 0004 Restarting 'demo.exe'...
2019/05/05 15:49:27 SUCCESS  ▶ 0005 './demo.exe' is running...
create table `user`
    -- --------------------------------------------------
    --  Table Structure for `demo/models.User`
    -- --------------------------------------------------
    CREATE TABLE IF NOT EXISTS `user` (
        `id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
        `name` varchar(255) NOT NULL DEFAULT '' ,
        `pwd` varchar(255) NOT NULL DEFAULT ''
    ) ENGINE=InnoDB;

2019/05/05 15:49:28.353 [I] [asm_amd64.s:1333]  http server Running on http://:8080

到数据库中查看创建结果:

use demo;
desc user;

注:“civ”为数据库名称。

ORM增

核心代码:

o := orm.NewOrm()
u := User{}

_, err := o.Insert(&u)

改造项目:

  1. 为了方便前后端分离,首先我们需要配置CORS来实现跨域:
    main.go中引入github.com/astaxie/beego/plugins/cors包:
package main

import (
	_ "civ/models"
	_ "civ/routers"
	"github.com/astaxie/beego"
	"github.com/astaxie/beego/plugins/cors"
)

func main() {
	beego.InsertFilter("*", beego.BeforeRouter, cors.Allow(&cors.Options{
		//允许访问所有源
		AllowAllOrigins: true,
		//可选参数"GET", "POST", "PUT", "DELETE", "OPTIONS" (*为所有)
		//其中Options跨域复杂请求预检
		AllowMethods:   []string{"*"},
		//指的是允许的Header的种类
		AllowHeaders: 	[]string{"*"},
		//公开的HTTP标头列表
		ExposeHeaders:	[]string{"Content-Length"},
	}))
	beego.Run()
}
  1. 为了方便查看API,我们使用API自动化文档

首先在routers/router.go文件最顶端添加注释:

// @APIVersion 1.0.0
// @Title DEMO API
// @Description Demo APIs.
// @Contact xxx@gmail.com
package routers

...

然后在controllers/user.go中,给UserController增加注释:

package controllers

import ...

// User APIs
type UserController struct {
	beego.Controller
}

然后修改conf/app.conf文件,添加:

EnableDocs = true

然后在具体的接口上填写注释。到时见下一步的具体的接口实现。

最后,运行bee run的时候添加几个参数:

bee run -gendoc=true -downdoc=true

编译完成后会在当前项目文件夹下生成swagger目录,部署这个目录,然后在浏览器打开即可看到生成的swagger api 文档。

  1. 按照MVC代码设计,首先我们在models/user.goUser新增一个Add方法:
package models

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

type User struct {
    Id int
    Name string
    Pwd string
}

func (u User) Add(item User) error {
    u.Name = strings.Trim(item.Name, " ")
    u.Pwd = strings.Trim(item.Pwd, " ")

    if u.Name == "" {
        return errors.New("请输入姓名")
    }
    
    if u.Pwd == "" || len(u.Pwd) < 3 {
        return errors.New("请输入长度大于等于3的密码")
    }
    
    o := orm.NewOrm()
    _, err := o.Insert(&u)
    
    return err
}

然后在models新增一个公共返回结构result.go

package models

type Code int32

const (
	SUCCESS Code = iota // value --> 0
	ERR_BIZ                       // value --> 1
	ERR_DATA                   // value --> 2
	ERR_AUTH                  // value --> 3
	ERR_LOST                  // value --> 4
	ERR_UNKNOW          // value --> 5
)

func (c Code) String() string {
    switch c {
	case SUCCESS:
		return "操作成功"
	case ERR_BIZ:
		return "业务操作失败"
	case ERR_DATA:
		return "数据操作失败"
	case ERR_AUTH:
		return "权限操作失败"
	case ERR_LOST:
		return "操作不存在"
	case ERR_UNKNOW:
		return "未知错误200"
	default:
		return "未知错误"
	}
}

type Result struct {
	Code Code
	Msg string
	Data interface{}
}

然后在controllers新增一个user.go,同时在这里添加api注释,以生成api文档:

package controllers

import (
	"civ/models"
	"encoding/json"
	"github.com/astaxie/beego"
)

type UserController struct {
	beego.Controller
}

// @Title AddUser
// @Description Add users
// @Param   user     formData    models.UserAddObj        "The user list for add"
// @router /add [post]
func (c *UserController) Post() {
	r := models.Result{}

	usr := models.User{}

	var err error
	var arr []models.User
	var errs []error
	if err = json.Unmarshal(c.Ctx.Input.RequestBody, &arr); err == nil {

		for _, item := range arr {
			err := usr.Add(item)

			if err != nil {
				errs = append(errs, err)
			}
		}

		r.Data = nil
		r.Msg = "新增用户成功"
		r.Code = models.SUCCESS

		if len(errs) > 0 {
			r.Data = nil
			r.Msg = errs[0].Error()
			r.Code = models.ERR_DATA
		}

	} else {
		r.Data = nil
		r.Msg = err.Error()
		r.Code = models.ERR_BIZ
	}

	c.Data["json"] = r
	c.ServeJSON()
}

然后在routers/router.go中,添加/user路由:

// @APIVersion 1.0.0
// @Title DEMO API
// @Description Demo APIs.
// @Contact xxx@gmail.com
package routers

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

func init() {
	ns := beego.NewNamespace("/v1",
		beego.NSNamespace("/",
			beego.NSInclude(
				&controllers.MainController{},
			),
		),
		beego.NSNamespace("/user",
			beego.NSInclude(
				&controllers.UserController{},
			),
		),
	)

	beego.AddNamespace(ns)
}

由于我们要在UserController中访问Request Body,需要在conf/app.conf中添加:

copyrequestbody = true

至此服务端就算是完成,然后是前端提交表单代码,这里使用ajax提交:

...
<body>
<div>
    姓名:<input type="text" name="r2name">
    密码:<input type="password" name="r2pwd">
    <button type="button" id="r2b">请求user接口并插入上面的数据</button>
</div>


<script src="./node_modules/jquery/dist/jquery.js"></script>
<script type="text/javascript">
    $(document).ready(() => {
        $('#r2b').on('click', function () {
            new BeegoRequests().r2();
        });

    });

    // ajax请求简单封装
    class Request {
        constructor() {
            this.DEFAULT = {
                host: 'http://localhost:8080/v1',
                url: '/',
                type: 'POST',
                data: ''
            };
        }

        DEFAULT;

        r(option = {}) {
            const opt = Object.assign(this.DEFAULT, option);
            return new Promise((resolve, reject) => {
                let data = opt.data;
                if (opt.type.toUpperCase() === 'POST')
                    data = JSON.stringify(data);
                $.ajax({
                    url: opt.host + opt.url,
                    type: opt.type,
                    data: data,
                    success(res) {
                        resolve(res);
                    },
                    error(err) {
                        reject(err);
                    }
                });
            });
        }
    }

    class BeegoRequests extends Request {
        constructor() {
            super();
        }

        r2() {
            const name = $('input[name="r2name"]').val();
            const pwd = $('input[name="r2pwd"]').val();
            const data = [{ name: name, pwd: pwd }];

            this.r({
                url: '/user/add',
                data: data
            }).then(res => {
                console.log(res);
            }).catch(err => {

            });
        }
    }

</script>
</body>

ORM查

核心代码:

o := orm.NewOrm()
qs := o.QueryTable("user")
_, err := qs.Filter("name__icontains", strings.Trim(name, " ")).All(&list)

实现过程:

简单实现一个根据name模糊查询的接口:

首先在models/user.go中新增一个List方法:

func (u User) List(name string) ([]User, error) {
	var list []User
	o := orm.NewOrm()
	qs := o.QueryTable("user")
	_, err := qs.Filter("name__icontains", strings.Trim(name, " ")).All(&list)

	return list, err
}

然后在controllers/user.go里新增一个List方法:

// @Title GetUserList
// @Description Get user list
// @Param  name query string "The filter key of Name"
// @router /list [get]
func (c *UserController) List() {
	r := models.Result{}
	usr := models.User{}
	name := c.GetString("name")

	userList, err := usr.List(name)

	r.Data = userList
	r.Code = models.SUCCESS
	r.Msg = "查询成功"

	if err != nil {
		r.Data = nil
		r.Code = models.ERR_DATA
		r.Msg = "查询用户不存在"
	}

	c.Data["json"] = r
	c.ServeJSON()
}

至此服务端完成,然后前端:

<html>
...
<body>

<div>
    查询姓名:<input type="text" name="r3name">
    <button type="button" id="r3b">根据姓名获取用户列表</button>
</div>


<script src="./node_modules/jquery/dist/jquery.js"></script>
<script type="text/javascript">
    $(document).ready(() => {
        $('#r3b').on('click', function () {
            new BeegoRequests().r3();
        });
    });

    class Request {
        ...
    }

    class BeegoRequests extends Request {
        ...

        r3() {
            const name = $('input[name="r3name"]').val();
            this.r({
                type: 'GET',
                url: '/user/list',
                data: {
                    name: name
                }
            }).then(res => {
                console.log(res);
            }).catch(err => {

            });
        }
    }

</script>
</body>
</html>

这里只是个人入门过程,更多内容参阅beego官方文档
源码地址参见Github

posted @   古宝只  阅读(1455)  评论(1编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
点击右上角即可分享
微信分享提示