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项目。
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)
改造项目:
- 为了方便前后端分离,首先我们需要配置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()
}
- 为了方便查看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 文档。
- 按照MVC代码设计,首先我们在
models/user.go
为User
新增一个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入门笔记的更多相关文章
- 每天成长一点---WEB前端学习入门笔记
WEB前端学习入门笔记 从今天开始,本人就要学习WEB前端了. 经过老师的建议,说到他每天都会记录下来新的知识点,每天都是在围绕着这些问题来度过,很有必要每天抽出半个小时来写一个知识总结,及时对一天工 ...
- ES6入门笔记
ES6入门笔记 02 Let&Const.md 增加了块级作用域. 常量 避免了变量提升 03 变量的解构赋值.md var [a, b, c] = [1, 2, 3]; var [[a,d] ...
- [Java入门笔记] 面向对象编程基础(二):方法详解
什么是方法? 简介 在上一篇的blog中,我们知道了方法是类中的一个组成部分,是类或对象的行为特征的抽象. 无论是从语法和功能上来看,方法都有点类似与函数.但是,方法与传统的函数还是有着不同之处: 在 ...
- React.js入门笔记
# React.js入门笔记 核心提示 这是本人学习react.js的第一篇入门笔记,估计也会是该系列涵盖内容最多的笔记,主要内容来自英文官方文档的快速上手部分和阮一峰博客教程.当然,还有我自己尝试的 ...
- redis入门笔记(2)
redis入门笔记(2) 上篇文章介绍了redis的基本情况和支持的数据类型,本篇文章将介绍redis持久化.主从复制.简单的事务支持及发布订阅功能. 持久化 •redis是一个支持持久化的内存数据库 ...
- redis入门笔记(1)
redis入门笔记(1) 1. Redis 简介 •Redis是一款开源的.高性能的键-值存储(key-value store).它常被称作是一款数据结构服务器(data structure serv ...
- OpenGLES入门笔记四
原文参考地址:http://www.cnblogs.com/zilongshanren/archive/2011/08/08/2131019.html 一.编译Vertex Shaders和Fragm ...
- OpenGLES入门笔记三
在入门笔记一中比较详细的介绍了顶点着色器和片面着色器. 在入门笔记二中讲解了简单的创建OpenGL场景流程的实现,但是如果在场景中渲染任何一种几何图形,还是需要入门笔记一中的知识:Vertex Sha ...
- unity入门笔记
我于2010年4月1日硕士毕业加入完美时空, 至今5年整.刚刚从一家公司的微端(就是端游技术+页游思想, 具体点就是c++开发, directX渲染, 资源采取所需才会下载)项目的前端主程职位离职, ...
随机推荐
- ubuntu进程监视器htop 清除黄色内存(缓存)
大意是:对于CPU显示条: 蓝色为:低优先级的线程 绿色为:正常优先级线程 红色为:内核线程 对于内存显示条: 蓝色为:缓冲区(buffers) 绿色为:已使用的内存 (橘)黄色为:高速缓存(cach ...
- 完美解决: org.apache.ibatis.binding.BindingException Invalid bound statement (not found)
异常描述: org.apache.ibatis.binding.BindingException: Invalid bound statement (not found) 原因: springboot ...
- EnvironmentError: mysql_config not found
Collecting MySQL-python==1.2.5 (from -r requirementsNoGit.txt (line 9)) Using cached https://files.p ...
- FineReport 交叉报表
交叉报表 - FineReport报表官网http://www.finereport.com/knowledge/professional/crossreport.html FineReport--- ...
- C++11智能指针之std::unique_ptr
C++11智能指针之std::unique_ptr uniqut_ptr是一种对资源具有排他性拥有权的智能指针,即一个对象资源只能同时被一个unique_ptr指向. 一.初始化方式 通过new云 ...
- Spring中好玩的注解和接口
测试中: 一.unit中集中基本注解,是必须掌握的. @BeforeClass – 表示在类中的任意public static void方法执行之前执行 @AfterClass – 表示在类中的任意p ...
- (转载)文献可视化--vosviewer入门
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/weixin_42613298/artic ...
- docker容器中解决出现:^H^H^H^H
docker容器中解决出现:^H^H^H^H 环境:docker容器是debain系统 解决: 把stty erase ^H 添加到.bash_profile中 vim /etc/profile st ...
- Linux系统swappiness参数在内存与交换分区之间优化作用
http://blog.sina.com.cn/s/blog_13cc013b50102wskd.html swappiness的值的大小对如何使用swap分区是有着很大的联系的.swappiness ...
- ecshop数据表结构说明
深深地看看这个吧,会很有帮助的... ecs_account_log 用户帐号情况记录表,包括资金和积分等 log_id mediumint 自增ID号user_id mediumint 用户登录后保 ...