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项目。

sequenceDiagram
Browser->>Server: http:localhost:8080
Server->>Server: Main.go
Server->>Server: router.Init()
Server->>Server: Controller.Get()
Server->>Server: View
Server-->>Browser: index.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

beego入门笔记的更多相关文章

  1. 每天成长一点---WEB前端学习入门笔记

    WEB前端学习入门笔记 从今天开始,本人就要学习WEB前端了. 经过老师的建议,说到他每天都会记录下来新的知识点,每天都是在围绕着这些问题来度过,很有必要每天抽出半个小时来写一个知识总结,及时对一天工 ...

  2. ES6入门笔记

    ES6入门笔记 02 Let&Const.md 增加了块级作用域. 常量 避免了变量提升 03 变量的解构赋值.md var [a, b, c] = [1, 2, 3]; var [[a,d] ...

  3. [Java入门笔记] 面向对象编程基础(二):方法详解

    什么是方法? 简介 在上一篇的blog中,我们知道了方法是类中的一个组成部分,是类或对象的行为特征的抽象. 无论是从语法和功能上来看,方法都有点类似与函数.但是,方法与传统的函数还是有着不同之处: 在 ...

  4. React.js入门笔记

    # React.js入门笔记 核心提示 这是本人学习react.js的第一篇入门笔记,估计也会是该系列涵盖内容最多的笔记,主要内容来自英文官方文档的快速上手部分和阮一峰博客教程.当然,还有我自己尝试的 ...

  5. redis入门笔记(2)

    redis入门笔记(2) 上篇文章介绍了redis的基本情况和支持的数据类型,本篇文章将介绍redis持久化.主从复制.简单的事务支持及发布订阅功能. 持久化 •redis是一个支持持久化的内存数据库 ...

  6. redis入门笔记(1)

    redis入门笔记(1) 1. Redis 简介 •Redis是一款开源的.高性能的键-值存储(key-value store).它常被称作是一款数据结构服务器(data structure serv ...

  7. OpenGLES入门笔记四

    原文参考地址:http://www.cnblogs.com/zilongshanren/archive/2011/08/08/2131019.html 一.编译Vertex Shaders和Fragm ...

  8. OpenGLES入门笔记三

    在入门笔记一中比较详细的介绍了顶点着色器和片面着色器. 在入门笔记二中讲解了简单的创建OpenGL场景流程的实现,但是如果在场景中渲染任何一种几何图形,还是需要入门笔记一中的知识:Vertex Sha ...

  9. unity入门笔记

    我于2010年4月1日硕士毕业加入完美时空, 至今5年整.刚刚从一家公司的微端(就是端游技术+页游思想, 具体点就是c++开发, directX渲染, 资源采取所需才会下载)项目的前端主程职位离职, ...

随机推荐

  1. C格式字符串转为二叉树

    最近在LeetCode做题,二叉树出现错误时不好排查,于是自己写了一个函数,将前序遍历格式字串转换成二叉树. 形如 "AB#D##C##" 的字符串,"#"表示 ...

  2. QTextToSpeech Win7奔溃

    在linux下,它是调用speech-dispatcher.在其它不同的平台上,调用各自平台的TTS引擎.所以在使用的时候,要确保本地的TTS引擎是可用的. 本地TTS引擎不可用可能会在声明QText ...

  3. 屏幕录制 -- web前端

    前端使用html5.ffmpeg实现录屏摄像等功能 https://tong-h.github.io/2018/11/06/streamcapture/ JSCapture – 基于 HTML5 实现 ...

  4. Eclipse创建的Java Web项目,如何启用外置浏览器访问jsp或者html页面

    当我们用Eclipse创建了一个Java Web项目,想访问一个jsp或者html页面时,通常会在目标页面(以jsp为例)上点击鼠标右键,选择[Run As]——>[Run on Server] ...

  5. 关于Android8.0 静态注册广播 行为变更的说明。

    Andorid 8.0 对广播的使用做了变更. 当广播接收器使用静态注册方式使用时,除了一些例外,这个接收器接收不到隐式广播. 注意这个“隐式”是重点. 看了网上几篇文章,对这个变更理解有误.错误的理 ...

  6. https://github.com/python/cpython/blob/master/Doc/library/contextlib.rst 被同一个线程多次获取的同步基元组件

    # -*- coding: utf-8 -*- import time from threading import Lock, RLock from datetime import datetime ...

  7. 前端通用下载文件方法(兼容IE)

    之前在网上看到一个博主写的前端通用的下载文件的方法,个人觉得很实用,所以mark一下,方便以后查阅 源文地址(源文还有上传/下载excel文件方法) 因为项目要求要兼容IE浏览器,所以完善了一下之前博 ...

  8. 小D课堂 - 零基础入门SpringBoot2.X到实战_第6节 SpringBoot拦截器实战和 Servlet3.0自定义Filter、Listener_24、深入SpringBoot过滤器和Servlet配置过滤器

    笔记 1.深入SpringBoot2.x过滤器Filter和使用Servlet3.0配置自定义Filter实战(核心知识)     简介:讲解SpringBoot里面Filter讲解和使用Servle ...

  9. Dart泛型

    /* 通俗理解:泛型就是解决 类 接口 方法的复用性.以及对不特定数据类型的支持(类型校验) */ //只能返回string类型的数据 // String getData(String value){ ...

  10. zabbix使用fping监控任意两个节点之间的网络质量、丢包率和响应时间

    zabbix使用fping监控任意两个节点之间的网络质量.丢包率和响应时间 之前的博文 使用zabbix3..4的ICMP Ping模版实现对客户端网络状态的监控 https://www.cnblog ...