golang(beego框架);

第一单元
一、beego框架的概念
二、beego特点
三、用途
 
一、beego框架的概念
是一款基于go语言快速开发API和web应用的框架
rest:表象状态转移 restful 表象状态转移的
符合restful设计风格的接口
请求方式:post 新增资源,put/id:更新或修改资源,get:获取资源列表,get/id:获取单个资源,delete/id:删除资源
二、特性
1.简单化
MVC
M:model,模型层,主要封装数据处理
V:view,视图层,主要用来显示控制器处理后的结果数据和交互渲染
C:Controller控制器,主要用来处理用户请求业务逻辑
QPS:Query Per Second:每秒请求次数
TPS:Transer Per second:每秒传输次数
2.智能化
3.模块化
4.高性能
 
bee命令工具
bee version 查看版本信息和环境配置信息
bee new 项目名 创建web项目
bee run 启动运行项目
bee api 项目名 创建api项目
bee migrate 运行数据库迁移文件
 
 
beego web项目
目录介绍
conf 存放配置文件
controllers 存放控制器文件
models 存放模型层文件
routers 存放路由文件
static 存放静态资源
tests 存放测试文件
views 存放视图文件
main.go 项目入口文件
 
 
第二单元 beego入门
 
一、路由概念
二、路由的使用
一、路由概念
路由是根据路由名对控制器和方法的映射
二、路由的使用
routers/router.php
1.get方式请求
使用方法:beego.Router(路由名, 控制器, "get:方法名")
示例代码
beego.Router("/list", &controllers.MainController{}, "get:List")
 
controllers/default.go
func (c *MainController) List() {
	c.TplName = "member/list.html"
}
 
2.多种请求方式
请求方式用逗号隔开
使用方法:beego.Router(路由名, 控制器, "get,post,delete,put:方法名")
3.任意请求方式
使用方法:beego.Router(路由名, 控制器, "*:方法名")
beego.Router("/list", &controllers.MainController{}, "*:List")
 
4.自动路由
beego.AutoRouter(&controllers.Product{})
 
ProductController.go
 
package controllers
 
import (
	"github.com/astaxie/beego"
)
 
type Product struct {
	beego.Controller
}
 
func (this *Product) Login() {
	id := this.Input().Get("id")
	name := this.Input().Get("name")
	this.Ctx.WriteString(id + name)
	this.Ctx.WriteString("login")
}
 
func (this *Product) Logout() {
	this.Ctx.WriteString("Logout")
}
 
func (this *Product) List() {
	this.Ctx.WriteString("List")
}
 
 
访问方法:
/product/list
/product/login
 
 
第三单元 MVC架构
一.MVC概念
二.MVC优点
三.MVC缺点
 
一.MVC概念介绍
是一种软件架构的思想,将一个软件按照模型、视图、控制器进行划分。其中,模型用来封装业务逻辑,视图用来实现表示逻辑,控制器用来协调模型与视图(视图要通过控制器来调用模型,模型返回的处理结果也要先交给控制器,由控制器来选择合适的视图来显示 处理结果)。 1)模型: 业务逻辑包含了业务数据的加工与处理以及相应的基础服务(为了保证业务逻辑能够正常进行的事务、安全、权限、日志等等的功能模块) 2)视图:展现模型处理的结果;另外,还要提供相应的操作界面,方便用户使用。 3)控制器:视图发请求给控制器,由控制器来选择相应的模型来处理;模型返回的结果给控制器,由控制器选择合适的视图。
二、 MVC优点
1、低耦合性:
视图层和业务层分离,这样就允许更改视图层代码而不用重新编译模型和
控制器代码。同样,一个应用的业务流程或者业务规则的改变只需要改动
MVC的模型层即可,因为模型与控制器和视图相分离,所以很容易改变应用
程序的数据层和业务规则。
2、高重用性和可适用性
MVC模式允许你使用各种不同样式的视图来访问同一个服务器端的代码。它
包括任何WEB(HTTP)浏览器或者无线浏览器(wap),例如:很多数
据可能用HTML来表示,但是也有可能用WAP来表示,而这些表示所需要的仅令
是改变视图层的实现方式,而控制层和模型层无需做任何改变。
3、较低的生命周期成本
MVC使降低开发和维护用户接口的技术含量成为可能。
4、快速的部署
使用MVC模式使开发时间得到相当大的缩减,它使程序员
集中 精力于业务逻辑,界面程序员(HTML和JS开发人员)集中精力于表
现形式上
5、可维护性
分离视图层和业务层也使得WEB应用更便于维护和修改
6、有利于软件工程化管理
由于不同的层各司其职,没一层不同的应用具有某些相同的特征,有利于通过
工程化、工具化管理程序代码。
 
 
RESTful 接口请求
 
路由
beego.Router("/api", &controllers.MainController{})
控制器层
 
package controllers
 
import (
"github.com/astaxie/beego"
)
 
type MainController struct {
beego.Controller
}
 
func (c *MainController) Get() {
c.Ctx.WriteString("get")
 
}
 
func (c *MainController) Put() {
c.Ctx.WriteString("put")
 
}
 
func (c *MainController) Post() {
//c.Ctx.WriteString("post")
}
 
func (c *MainController) Delete() {
c.Ctx.WriteString("delete")
}
 
func (c *MainController) List() {
c.TplName = "member/list.html"
}
 
 
第四单元 参数配置
 
1.配置文件存放位置
conf/app.conf
xml:EXtensible Markup Language
html:
json:
xml和json的用途:用于数据交互与共享
xml json: json_encode,json_decode
 
appname:项目名称
runmode:运行级别,比如可设置为:dev,test,prod
httport:监听端口号
httpAddr:服务器地址
autorender:自动加载视图 默认为true,比如:true:自动加载,false:不自动加载
 
mysqluser = "root"
mysqlpass = "root"
mysqlurls = "127.0.0.1"
mysqldb = "beegotest"
redisurl = 127.0.0.1
redisport = 6379
 
2.获取配置参数
beego.AppConfig.String(参数名)
beego.AppConfig.String("runmode")
 
 
示例代码
appname = 1803a #项目名
 
runmode = test  #运行模式
 
autorender = false #自动加载视图
 
 
[dev]
httpport = 8088 #监听端口
dbhost = 127.0.0.1
dbport = 3306
dbuser = root
dbpwd = root
dbname = 1803a
 
[test]
httpport = 8080 #监听端口
dbhost = test.com
dbport = 3306
dbuser = test
dbpwd = test123456
dbname = 1803a
 
main.go获取
package main
 
import (
	_ "1803a/routers"
	"fmt"
 
	"github.com/astaxie/beego"
)
 
func init() {
	runmode := beego.AppConfig.String("runmode")
	fmt.Printf("runmode:" + runmode)
}
 
func main() {
	beego.Run()
}
 
 
多运行模式获取参数
用法:beego.AppConfig.String(运行模式::参数名)
例如:beego.AppConfig.String("test::httpport") 获取test模式下的httpport
 
多配置文件
include:引入子文件
 
app.conf
include "dev.conf"
include "test.conf"
 
dev.conf:
[dev]
httpport = 8088
dbhost = 127.0.0.1
dbport = 3306
dbuser = root
dbpwd = root
dbname = 1803a
 
 
test.conf
 
[test]
httpport = 8080
dbhost = test.com
dbport = 3306
dbuser = test
dbpwd = test123456
dbname = 1803a
 
 
第五单元 go操作mysql
一、标准包引用
二、实现增删改查功能
 
一、标准包引用
 
github.com/go-sql-driver/mysql (mysql驱动)
github.com/jmoiron/sqlx (基于mysql驱动的封装)
命令行输入 :
go get github.com/go-sql-driver/mysql
go get github.com/jmoiron/sqlx
 
二、实现增删改查功能
1.数据库连接
用法:database, err := sqlx.Open(数据库驱动, 用户名:密码@tcp(db地址:端口)/数据库名)
database, err := sqlx.Open("mysql", "root:root@tcp(127.0.0.1:3306)/test")
 
示例代码
// test
package main
 
import (
	"fmt"
 
	_ "github.com/go-sql-driver/mysql"
	"github.com/jmoiron/sqlx"
)
 
func main() {
 
	_, err := sqlx.Open("mysql", "root:root@tcp(127.0.0.1:3306)/1803a")
	if err != nil {
		fmt.Println("数据库连接失败", err.Error())
 
	} else {
		fmt.Println("数据库连接成功")
 
	}
 
}
 
2.新建表结构
CREATE TABLE `person` (
    `user_id` int(11) NOT NULL AUTO_INCREMENT,
    `username` varchar(260) DEFAULT NULL,
    `sex` varchar(260) DEFAULT NULL,
    `email` varchar(260) DEFAULT NULL,
    PRIMARY KEY (`user_id`)
  ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
 
3.新增功能实现
 
type Person struct {
    UserId   int    `db:"user_id"`
    Username string `db:"username"`
    Sex      string `db:"sex"`
    Email    string `db:"email"`
}
 
var Db *sqlx.DB
 
func init() {
    database, err := sqlx.Open("mysql", "root:root@tcp(127.0.0.1:3306)/test")
    if err != nil {
        fmt.Println("open mysql failed,", err)
        return
    }
    Db = database
    defer db.Close()  // 注意这行代码要写在上面err判断的下面
}
 
func main() {
    r, err := Db.Exec("insert into person(username, sex, email)values(?, ?, ?)", "stu001", "man", "stu01@qq.com")
    if err != nil {
        fmt.Println("exec failed, ", err)
        return
    }
    id, err := r.LastInsertId()
    if err != nil {
        fmt.Println("exec failed, ", err)
        return
    }
 
    fmt.Println("insert succ:", id)
}
 
4.查询实现
 
代码示例
 
package main
 
import (
	"fmt"
 
	_ "github.com/go-sql-driver/mysql"
	"github.com/jmoiron/sqlx"
)
 
type Person struct {
	UserId   int    `db:"user_id"`
	Username string `db:"username"`
	Sex      string `db:"sex"`
	Email    string `db:"email"`
}
 
var Db *sqlx.DB
 
func init() {
	database, err := sqlx.Open("mysql", "root:root@tcp(127.0.0.1:3306)/1803a")
	if err != nil {
		fmt.Println("open mysql failed,", err)
		return
	}
	Db = database
	//defer Db.Close() // 注意这行代码要写在上面err判断的下面
}
 
func main() {
	var person []Person
	err := Db.Select(&person, "select user_id, username, sex, email from person where user_id=?", 1)
	if err != nil {
		fmt.Println("exec failed, ", err)
		return
	}
 
	fmt.Println("select succ:", person)
}
5.更新操作
 
package main
 
import (
	"fmt"
 
	_ "github.com/go-sql-driver/mysql"
	"github.com/jmoiron/sqlx"
)
 
type Person struct {
	UserId   int    `db:"user_id"`
	Username string `db:"username"`
	Sex      string `db:"sex"`
	Email    string `db:"email"`
}
 
var Db *sqlx.DB
 
func init() {
	database, err := sqlx.Open("mysql", "root:root@tcp(127.0.0.1:3306)/1803a")
	if err != nil {
		fmt.Println("open mysql failed,", err)
		return
	}
	Db = database
	//defer Db.Close() // 注意这行代码要写在上面err判断的下面
}
 
func main() {
	res, err := Db.Exec("update person set username=? where user_id=?", "stu0003", 1)
	if err != nil {
		fmt.Println("exec failed, ", err)
		return
	}
	row, err := res.RowsAffected()
	if err != nil {
		fmt.Println("rows failed, ", err)
	}
	fmt.Println("update succ:", row)
}
 
6.删除操作
package main
 
import (
	"fmt"
 
	_ "github.com/go-sql-driver/mysql"
	"github.com/jmoiron/sqlx"
)
 
type Person struct {
	UserId   int    `db:"user_id"`
	Username string `db:"username"`
	Sex      string `db:"sex"`
	Email    string `db:"email"`
}
 
var Db *sqlx.DB
 
func init() {
	database, err := sqlx.Open("mysql", "root:root@tcp(127.0.0.1:3306)/1803a")
	if err != nil {
		fmt.Println("open mysql failed,", err)
		return
	}
	Db = database
	//defer Db.Close() // 注意这行代码要写在上面err判断的下面
}
 
func main() {
	res, err := Db.Exec("delete from person where user_id=?", 1)
	if err != nil {
		fmt.Println("exec failed, ", err)
		return
	}
	row, err := res.RowsAffected()
	if err != nil {
		fmt.Println("rows failed, ", err)
	}
	fmt.Println("delete succ:", row)
}
 
第六单元 go操作redis
 
一、redis介绍
二、go redis使用
 
一、redis介绍
redis是KV结构的NOsql数据库
redis可以作为缓存使用,减少DB的负载
redis常用数据类型:
字符串:主要用于单一的字符串数据存储
哈希:主要存储对象数据的,比如:点赞,评论,收藏,关注
列表:主要于消息中间件,比如:解耦,肖峰等
集合:主要用于共同好友,粉丝
有序集合:主要用于排行榜
 
二、go redis使用
1.go 连接redis
redis.Dial("tcp", "redis主机地址:端口号")
 
package main
 
import (
	"fmt"
 
	"github.com/garyburd/redigo/redis"
)
 
func main() {
	c, err := redis.Dial("tcp", "localhost:6379") //redis连接
	if err != nil {
		fmt.Println("conn redis failed,", err)
		return
	}
 
	fmt.Println("redis conn success")
 
	defer c.Close()
}
 
2.redis字符串操作
package main
 
import (
	"fmt"
 
	"github.com/garyburd/redigo/redis"
)
 
func main() {
	c, err := redis.Dial("tcp", "localhost:6379")
	if err != nil {
		fmt.Println("conn redis failed,", err)
		return
	}
 
	defer c.Close()
	_, err = c.Do("Set", "key", 100)
	if err != nil {
		fmt.Println(err)
		return
	}
 
	r, err := redis.Int(c.Do("Get", "key"))
	if err != nil {
		fmt.Println("get abc failed,", err)
		return
	}
 
	fmt.Println(r)
}
 
3. 字符串批量操作
 
package main
 
import (
	"fmt"
 
	"github.com/garyburd/redigo/redis"
)
 
func main() {
	c, err := redis.Dial("tcp", "localhost:6379")
	if err != nil {
		fmt.Println("conn redis failed,", err)
		return
	}
 
	defer c.Close()
	_, err = c.Do("MSet", "var1", 100, "var2", 300, "var3", 400)
	if err != nil {
		fmt.Println(err)
		return
	}
 
	r, err := redis.Ints(c.Do("MGet", "var1", "var2", "var3"))
	if err != nil {
		fmt.Println("get abc failed,", err)
		return
	}
 
	for _, v := range r {
		fmt.Println(v)
	}
}
 
4.设置过期时间
用法:c.Do("expire", key, 秒数)
c.Do("expire", "var1", 10)
 
代码示例
 
package main
 
import (
	"fmt"
 
	"github.com/garyburd/redigo/redis"
)
 
func main() {
	c, err := redis.Dial("tcp", "localhost:6379")
	if err != nil {
		fmt.Println("conn redis failed,", err)
		return
	}
 
	defer c.Close()
	_, err = c.Do("expire", "var2", 10)
	if err != nil {
		fmt.Println(err)
		return
	}
}
5.LIST操作
package main
 
import (
	"fmt"
 
	"github.com/garyburd/redigo/redis"
)
 
func main() {
	c, err := redis.Dial("tcp", "localhost:6379")
	if err != nil {
		fmt.Println("conn redis failed,", err)
		return
	}
 
	defer c.Close()
	// _, err = c.Do("lpush", "book_list", "abc", "ceg", 300)
	// if err != nil {
	// 	fmt.Println(err)
	// 	return
	// }
 
	r, err := redis.String(c.Do("lpop", "book_list"))
	if err != nil {
		fmt.Println("get abc failed,", err)
		return
	}
 
	fmt.Println(r)
}
 
6.哈希操作
 
package main
 
import (
	"fmt"
 
	"github.com/garyburd/redigo/redis"
)
 
func main() {
	c, err := redis.Dial("tcp", "localhost:6379")
	if err != nil {
		fmt.Println("conn redis failed,", err)
		return
	}
 
	defer c.Close()
	_, err = c.Do("HSet", "books", "name", "三国")
	if err != nil {
		fmt.Println(err)
		return
	}
 
	r, err := redis.String(c.Do("HGet", "books", "name"))
	if err != nil {
		fmt.Println("get abc failed,", err)
		return
	}
 
	fmt.Println(r)
}
 
 
 
第七单元 context模块
 
一、常用状态码
二、redirect跳转
 
一、常用状态码
200:请求成功
301:永久重定向
302:临时重定向
400:请求语法错误
401:用户验证未授权
403:无权限访问
404:找不到请求资源
405:请求方法被禁止
500:服务器内部错误
502:服务器网关报错
503:服务器暂停服务
504:网关请求超时
 
二、redirect跳转
用法:ctx.Redirect(statuscode int,url string)
代码示例
c.Ctx.Redirect(502, "http://www.tmall.com")
 
三、abort的使用
用法:c.abort(statuscode string)
代码示例
c.Abort("404")
 
四、Ctx.WriteString
用途:输出字符串
用法:Ctx.WriteString(content string) string
代码示例
c.Ctx.WriteString("hello,beego")
 
五、cookie设置与获取
cookie与session的区别
设置用法:Ctx.SetCookie(name string,value string)
获取用法:Ctx.GetCookie(name) string
代码示例
this.Ctx.SetCookie("username", "abc")            //cookie设置
cookieUsername := this.Ctx.GetCookie("username") //cookie获取
this.Ctx.WriteString(cookieUsername) //输出cookie
 
六、获取请求参数
 
  • GetString(key string) string
  • GetStrings(key string) []string
  • GetInt(key string) (int64, error)
  • GetBool(key string) (bool, error)
  • GetFloat(key string) (float64, error)
 
代码示例
 
name := this.GetString("name")
isvip, _ := this.GetBool("isvip")
num, _ := this.GetInt("num")
 
七、Ctx.Input() 接收请求数据
用法:Ctx.Input().Get(参数名) string
 
 
 
2.2.4 用于请求url
url := c.Ctx.Input.URL()
c.Ctx.WriteString(url)
//如访问127.0.0.1:8080 输出结果:/abc
site := c.Ctx.Input.Site()
c.Ctx.WriteString(site)
//如访问 http://127.0.0.1:8080 输出结果:http://127.0.0.1
schema := c.Ctx.Input.Scheme()
c.Ctx.WriteString(schema)
//如访问 http://127.0.0.1:8080/abc 输出结果:http
host := c.Ctx.Input.Host()
c.Ctx.WriteString(host)
isAjax := c.Ctx.Input.IsAjax()
beego.Info(isAjax)
ip := c.Ctx.Input.IP()
c.Ctx.Output.Body([]byte(ip))
2.2.9 获取ip
2.2.8 判断是否为ajax请求
2.2.7 host
2.2.6 请求的Scheme
2.2.5 请求站点地址site
 
 
第八单元 控制器数据接收和处理
 
一、表单内容与结构体的解析
二、url构建
三、多格格式输出
 
1.定义结构体
 
// user.go
package models
 
//学生结构定义
type Student struct {
Id int `form:"-"`
Username string
Email string
}
 
2.控制器定义
package controllers
 
import (
"1803a_chapter8/models"
 
"github.com/astaxie/beego"
)
 
type UserController struct {
beego.Controller
}
 
//添加页面方法
func (c *UserController) Add() {
 
c.TplName = "user.tpl"
}
 
//提交信息
func (c *UserController) Submit() {
user := models.User{} //模型层实例化
err := c.ParseForm(&user) //表单解析到结构体
 
if err == nil {
c.Data["json"] = user
c.ServeJSON()
//fmt.Println(user)
}
c.Ctx.WriteString("aaa")
//c.TplName = "user.tpl"
}
 
3.视图层定义
 
<!DOCTYPE html>
 
<html>
<head>
<title>Beego</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
 
<body>
 
<form id="user" method="post" action="/submit">
<div>用户名:<input id="username" name="username" type="text" /></div>
<div>邮箱地址:<input id="email" name="email" type="text" /></div>
 
<input id="submit" type="submit" value="提交">
 
</form>
 
</body>
</html>
 
 
 
 
 
4.路由定义
package routers
 
import (
"1803a_chapter8/controllers"
 
"github.com/astaxie/beego"
)
 
func init() {
beego.Router("/", &controllers.MainController{})
 
beego.Router("/add", &controllers.UserController{}, "get:Add")
 
beego.Router("/submit", &controllers.UserController{}, "post:Submit")
 
}
 
 
二、url构建
 
1.路由文件定义好的路由
 
beego.Router("/submit", &controllers.UserController{}, "post:Submit")
2.生成路由
url := beego.URLFor("UserController.Submit")
 
输出结果:/submit
 
三、多种数据格式输出
1.json格式
 
c.Data["json"] = user
c.ServeJSON()
 
2.xml
 
c.Data["xml"] = user
c.ServeXML()
 
四、错误处理
 
1.c.Redirect(url string, http状态码 int)
 
 
2.error自定义
 
代码示例
main.go
 
package main
 
import (
	"1803a_chapter8/controllers"
	_ "1803a_chapter8/routers"
 
	"github.com/astaxie/beego"
)
 
func main() {
	beego.ErrorController(&controllers.ErrorController{}) //错误页处理
	beego.Run()
}
 
2.控制器
errorController.go
package controllers
 
import (
"github.com/astaxie/beego"
)
 
type ErrorController struct {
beego.Controller
}
 
func (c *ErrorController) Error404() {
//c.Data["content"] = "page not found"
c.TplName = "error/404.tpl"
}
 
func (c *ErrorController) Error502() {
//c.Data["content"] = "server error"
c.TplName = "error/502.tpl"
}
 
3.view
error/502.tpl
<!DOCTYPE html>
 
<html>
<head>
<title>Beego</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
 
</head>
 
<body>
<div style="margin-top:200px;text-align:center;">
<img style="width:50%" src="/static/img/502.jpg" />
</div>
</body>
</html>
 
五、日志记录
 
beego.Emergency("this is emergency")
beego.Alert("this is alert")
beego.Critical("this is critical")
beego.Error("this is error")
beego.Warning("this is warning")
beego.Notice("this is notice")
beego.Informational("this is informational")
beego.Debug("this is debug")
 
beego.SetLogger("file", `{"filename":"logs/mylog.log"}`)
 
beego.BeeLogger.DelLogger("console")
 
 
 
第九单元 ORM
 
一、ORM介绍
1.ORM:Object Relational Mapping 对象关系映射
2.作用:是把对对象的增删改查操作转换为sql
3.支持的数据库驱动
mysql sqlite3 postgresql oracle
 
4.优点
4.1 支持golang语言的所有数据类型,比如:字符串,整型,布尔等
4.2 学习比较简单,采用的是CRUD风格
4.3 表关联:one2one,one2many,many2many
4.4 跨库查询
4.5 使用原生SQL查询
4.6 比较稳定,性能好
 
二、ORM的使用
 
2.1 安装ORM
go get github.com/astaxie/beego/orm
 
2.2 ORM增删改查演示
 
orm.RegisterDataBase("default", "mysql", "root:root@tcp(127.0.0.1:3306)/1712a")
orm.RunSyncdb("default", false, true) //修改model字段自动同步数据表
 
 
步骤1.main.go
package main
 
import (
	_ "1803a_chapter9/routers"
 
	"github.com/astaxie/beego"
	"github.com/astaxie/beego/orm"
	_ "github.com/go-sql-driver/mysql"
)
 
//初始化函数定义
func init() {
	//注册mysql驱动
	orm.RegisterDataBase("default", "mysql", "root:root@tcp(127.0.0.1:3306)/1803a")
   //同步结构体到数据表	
   orm.RunSyncdb("default", false, true)
}
 
func main() {
	beego.Run()
}
 
 
步骤2.路由定义 routes/router.go
package routers
 
import (
	"1803a_chapter9/controllers"
 
	"github.com/astaxie/beego"
)
 
func init() {
	beego.Router("/", &controllers.MainController{})
 
	beego.Router("/add", &controllers.MemberController{}, "post:AddMember")
	beego.Router("/details/:id", &controllers.MemberController{}, "get:Details")
	beego.Router("/list", &controllers.MemberController{}, "get:MemberList")
	beego.Router("/update/:id", &controllers.MemberController{}, "put:UpdateMember")
	beego.Router("/delete/:id", &controllers.MemberController{}, "delete:DeleteMember")
 
}
 
 
 
步骤3.模型定义 Models.go
// Model
package models
 
import (
	"github.com/astaxie/beego/orm"
)
 
type Member struct {
	Id    int    `orm:"column(id);size(50) auto" description:"id"`
	Name  string `orm:"column(name);size(50)" description:"名称"`
	Email string `orm:"column(email);size(50)" description:"邮箱"`
	Age   int    `orm:"column(age);size(4)" description:"年龄"`
}
 
func init() {
	orm.RegisterModel(new(Member))) //注册模型
}
 
步骤4.控制器定义 controllers/memberController.go
package controllers
 
import (
	"1803a_chapter9/models"
	"strconv"
 
	"github.com/astaxie/beego"
	"github.com/astaxie/beego/orm"
)
 
type MemberController struct {
	beego.Controller
}
 
//会员信息添加
func (c *MemberController) AddMember() {
 
	reJson := make(map[string]interface{})
	c.Data["json"] = reJson
	defer c.ServeJSON()
	o := orm.NewOrm()
	var member models.Member
	member.Name = c.GetString("name")
	member.Email = c.GetString("email")
	member.Age, _ = c.GetInt("age", 18)
 
	if member.Name == "" {
		reJson["message"] = "用户名不能为空"
		reJson["status"] = "failed"
		return
	}
 
	_, err := o.Insert(&member)
	if err == nil {
		reJson["status"] = "ok"
		reJson["message"] = "添加成功"
	} else {
		reJson["status"] = "faild"
		reJson["message"] = "添加失败"
	}
 
}
 
//单个信息查询
func (c *MemberController) Details() {
 
	idStr := c.Ctx.Input.Param(":id")
	id, _ := strconv.Atoi(idStr)
	reJson := make(map[string]interface{})
	c.Data["json"] = reJson
	defer c.ServeJSON()
 
	var memberDetails []*models.Member
	om := orm.NewOrm()
 
	om.QueryTable("member").Filter("id", id).One(&memberDetails)
	if len(memberDetails) == 0 {
		reJson["status"] = "failed"
		reJson["message"] = "无此数据"
	} else {
		reJson["status"] = "ok"
		reJson["message"] = "查询成功"
	}
 
	reJson["data"] = &memberDetails
 
}
 
//列表查询
func (c *MemberController) MemberList() {
 
	reJson := make(map[string]interface{})
	c.Data["json"] = reJson
	defer c.ServeJSON()
 
	var memberList []*models.Member
	om := orm.NewOrm()
 
	om.QueryTable("member").All(&memberList)
	if len(memberList) == 0 {
		reJson["status"] = "failed"
		reJson["message"] = "无数据"
	} else {
 
		reJson["status"] = "ok"
		reJson["message"] = "查询成功"
	}
 
	reJson["data"] = &memberList
 
}
 
//单个更新
func (c *MemberController) UpdateMember() {
	idStr := c.Ctx.Input.Param(":id")
	id, _ := strconv.Atoi(idStr)
	o := orm.NewOrm()
	var member models.Member
	member.Id = id
 
	reJson := make(map[string]interface{})
	c.Data["json"] = reJson
	defer c.ServeJSON()
 
	if o.Read(&member) == nil {
		member.Name = c.GetString("name")
		member.Email = c.GetString("email")
		member.Age, _ = c.GetInt("age")
		if _, err := o.Update(&member); err == nil {
			reJson["status"] = "ok"
			reJson["message"] = "更新成功"
 
		}
	}
 
}
 
//删除单条信息
func (c *MemberController) DeleteMember() {
 
	idStr := c.Ctx.Input.Param(":id")
	id, _ := strconv.Atoi(idStr)
 
	o := orm.NewOrm()
	var member models.Member
	member.Id = id
 
	reJson := make(map[string]interface{})
	c.Data["json"] = reJson
	defer c.ServeJSON()
 
	if num, err := o.Delete(&member); err == nil {
		reJson["status"] = "ok"
		reJson["message"] = "删除成功"
	} else {
		reJson["status"] = "failed"
		reJson["message"] = "删除失败"
	}
 
}
 
 
 
第十单元 ORM高级使用
 
 
 
 
第十一单元 beego验证
 
一、原生正则使用
//初始化结构体对象的方法
func Compile(expr string) (*Regexp, error)
//和Compile函数相似,但是该方法支持POSIX协议,可以支持类似`egrep`的语法
func CompilePOSIX(expr string) (*Regexp, error)
 
//Must系列函数和上面两个函数相似,但是不会返回error,如果有异常直接panic
func MustCompile(str string) *Regexp
 
//在字符串中是否匹配到re定义的字符串,匹配返回true
func (re *Regexp) MatchString(s string) bool
 
 
//结构体方法.常用的几个
//在字符串s中查找完全匹配正则表达式re的字符串.如果匹配到就停止不进行全部匹配,如果匹配不到就输出空字符串
func (re *Regexp) FindString(s string) string
 
//在字符串s中匹配re表达式,n表示匹配的次数,-1表示匹配整个字符串。返回字符串切片
func (re *Regexp) FindAllString(s string, n int) []string
 
//在src中匹配re,并替换为repl,该种方式中repl中的$符号会展开实际的变量,通常用在回溯查找中
func (re *Regexp) ReplaceAllString(src, repl string) string
 
 
代码示例
 
r, _ := regexp.Compile("[a-z]")
	// fmt.Println(r.MatchString("adddd"))
 
	//fmt.Println(r.FindString("abd123"))
	fmt.Println(r.FindAllString("abd123", -1))
	fmt.Println(r.ReplaceAllString("abd1234", "*"))
 
二、beego validation验证使用
 
 
package controllers
 
import (
	"1803a_chapter9/models"
	"fmt"
	"strconv"
 
	"github.com/astaxie/beego"
	"github.com/astaxie/beego/orm"
	"github.com/astaxie/beego/validation"
)
 
type MemberController struct {
	beego.Controller
}
 
//会员信息添加
func (c *MemberController) AddMember() {
 
	reJson := make(map[string]interface{})
	c.Data["json"] = reJson
	defer c.ServeJSON()
	o := orm.NewOrm()
	var member models.Member
	member.Name = c.GetString("name")
	member.Email = c.GetString("email")
	member.Age, _ = c.GetInt("age", 18)
 
	valid := validation.Validation{}
	valid.Required(member.Name, "Name").Message("用户名不能为空!")
	valid.MinSize(member.Name, 5, "Name").Message("用户名必须5个字符以上")
	valid.Email(member.Email, "Email").Message("邮箱格式不正确")
	valid.Range(member.Age, 8, 20, "Age").Message("年龄不在范围内")

 
	if valid.HasErrors() {
		reJson["status"] = "failed"
		errMsg := []string{}
		for _, error := range valid.Errors {
			errMsg = append(errMsg, error.Message)
 
		}
		reJson["message"] = errMsg
		return
	}
 
	_, err := o.Insert(&member)
	if err == nil {
		reJson["status"] = "ok"
		reJson["message"] = "添加成功"
 
	} else {
		reJson["status"] = "faild"
		reJson["message"] = "添加失败"
 
	}
 
}
 
 
第十二单元 api和接口文档自动化
 
一、api自动化
二、接口文档自动化
 
一、api自动化
1.根据表结构生成应用
1.1 表结构
CREATE TABLE `books` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(30) DEFAULT '',
  `author` varchar(20) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 
1.2 入口文档修改
 
package main
 
import (
	_ "1803api/routers"
 
	"github.com/astaxie/beego"
	"github.com/astaxie/beego/orm"
	_ "github.com/go-sql-driver/mysql"
)
 
func init() {
	//【数据库配置】开始
	orm.RegisterDataBase("default", "mysql", "root:root@tcp(127.0.0.1:3306)/1803a")
	//【数据库配置】结束
	//自动更新数据表
	orm.RunSyncdb("default", false, true)
 
}
 
func main() {
	if beego.BConfig.RunMode == "dev" {
		beego.BConfig.WebConfig.DirectoryIndex = true
		beego.BConfig.WebConfig.StaticDir["/swagger"] = "swagger"
	}
	beego.Run()
}
1.3 bee命令
bee generate appcode -tables="books" -driver=mysql -conn="root:root@tcp(127.0.0.1:3306)/1803a" -level=3
level 1:model,2:model,controller,3:model,controller,route
 
 
1.4 改路由
// @APIVersion 1.0.0
// @Title beego Test API
// @Description beego has a very cool tools to autogenerate documents for your API
// @Contact astaxie@gmail.com
// @TermsOfServiceUrl http://beego.me/
// @License Apache 2.0
// @LicenseUrl http://www.apache.org/licenses/LICENSE-2.0.html
package routers
 
import (
	"1803api/controllers"
 
	"github.com/astaxie/beego"
)
 
func init() {
	ns := beego.NewNamespace("/v1",
 
		beego.NSNamespace("/books",
			beego.NSInclude(
				&controllers.BooksController{},
			),
		),
		beego.NSNamespace("/cates",
			beego.NSInclude(
				&controllers.CatesController{},
			),
		),
	)
	beego.AddNamespace(ns)
}
 
 
三、接口文档自动化
生成命令:
bee run -gendoc=true    -downdoc=true
 
api访问地址:
 
根据结构体生成应用
bee generate scaffold foods -fields="name:string,from:string" -driver=mysql -conn="root:root@tcp(127.0.0.1:3306)/1803a"
 
bee generate appcode -tables="products" -driver=mysql -conn="root:root@tcp(127.0.0.1:3306)/1803a" -level=2
 
 
type Like struct { ID int `orm:"primary_key"` Ip string `orm:"type:varchar(20);not null;index:ip_idx"` Ua string `orm:"type:varchar(256);not null;"` Title string `orm:"type:varchar(128);not null;index:title_idx"` Hash uint64 `orm:"unique_index:hash_idx;"` CreatedAt time.Time }
 
 
第十三单元 用户会话和缓存使用
 
一、用户会话介绍
 
1.session和cookie概念
2.session和cookie区别(掌握)
1、Cookie和Session都是会话技术,Cookie是运行在客户端,Session是运行在服务器端。
2、Cookie有大小限制以及浏览器在存cookie的个数也有限制,Session是没有大小限制和服务器的内存大小有关。
3、Cookie有安全隐患,通过拦截或本地文件找得到你的cookie后可以进行攻击。
4、Session是保存在服务器端上会存在一段时间才会消失,如果session过多会增加服务器的压力。
 
二、用户会话使用
 
session使用
 
1.session
模块安装
go get github.com/astaxie/beego/session
 
2.开启session
conf/app.conf
sessionon =true 默认不开启session
 
3.session设置
用法:c.SetSession(name interface{}, value interface{})
 
4.seesion获取
用法:c.GetSession(name interface{}) interface{}
 
代码示例
c.SetSession("sname", "jim") //设置session
sname := c.GetSession("sname") //获取session
c.Ctx.WriteString(sname.(string)) 转为string输出
 
5.session删除
c.DelSession(name interfaces{}) //根据key删除session信息
c.DestroySession() //清空所有session信息
 
代码示例
c.DelSession("sname") //根据session key删除
c.DestroySession() //清空所有session信息
 
cookie使用
 
1.cookie设置
Ctx.SetCookie(name string,value string,others interface{})
2.cookie获取
Ctx.GetCookie(name string) string
 
代码示例
c.Ctx.SetCookie("sname", "jim")
cookieSname := c.Ctx.GetCookie("sname")
c.Ctx.WriteString(cookieSname)
3.cookie删除
Ctx.SetCookie(name string,"")
 
 
三、缓存的使用
 
内存存储
bm, _ := cache.NewCache("memory", `{"interval":60}`)
文件存储
bm, _ := cache.NewCache("file", `{"CachePath":"./cache","FileSuffix":".cache","DirectoryLevel":"3","EmbedExpiry":"3600"}`)
 
1.设置缓存
Put(name string,value interface{},seconds )
2.获取缓存
Get(name string) interface{}
代码示例
bm, _ := cache.NewCache("memory", `{"interval":60}`)
bm.Put("sname", "jim", 60*time.Second) //设置缓存
cacheSname := bm.Get("sname")          //获取缓存
c.Ctx.WriteString(cacheSname.(string)) //输出缓存
 
3.判断缓存是否设置
IsExists(name string) bool
fmt.Println(bm.IsExists("sname"))
4.缓存删除
Delete(name string) bool
err := bm.Delete("sname")
if err != nil {
    fmt.Println(err.Error())
}
 
 
第十四单元 日志与httplib使用
 
一、logs日志使用
1.引入logs模块
import (
	"github.com/astaxie/beego/logs"
)
 
2.配置存储方式
2.1.写文件
logs.SetLogger(logs.AdapterFile, `{"filename":"logs/project.log","level":7,"maxlines":0,"maxsize":0,"daily":true,"maxdays":10,"color":true}`)
2.2.控制台输出
logs.SetLogger(logs.AdapterConsole)
 
2.2.多文件存储
logs.SetLogger(logs.AdapterMultiFile, `{"filename":"tt.log","separate":["emergency", "alert", "critical"]}`)
代码示例
 
//写文件
//logs.SetLogger(logs.AdapterFile, `{"filename":"logs/project.log","level":7,"maxlines":0,"maxsize":0,"daily":true,"maxdays":10,"color":true}`)
//多个文件
logs.SetLogger(logs.AdapterMultiFile, `{"filename":"tt.log","separate":["emergency", "alert", "critical"]}`)
logs.EnableFuncCallDepth(true) //显示行数
//控制台输出
//logs.SetLogger(logs.AdapterConsole) 
logs.Debug("my book is bought in the year of ", 2016)
logs.Info("this %s cat is %v years old", "yellow", 3)
logs.Warn("json is a type of kv like", map[string]int{"key": 2016})
logs.Error(1024, "is a very", "good game")
logs.Critical("oh,crash")
 
二、httplib
1.概念
在程序中模拟请求站点或接口
2.请求方式
2.1.get请求
Get(url string)
 
代码示例
req := httplib.Get("https://www.jd.com")
str, err := req.String()
if err != nil {
	c.Ctx.WriteString(err.Error())
}
c.Ctx.WriteString(str)
 
2.2.post请求
 
Post(url string)
req := httplib.Post("http://127.0.0.1:8080/adduser")
req.Param("username", "夏鑫辉")
req.Param("email", "xxh@sina.com")
str, err := req.String()
if err != nil {
	c.Ctx.WriteString(err.Error())
}
fmt.Println(str)
 
router.go
beego.Router("/adduser", &controllers.MainController{}, "post:Adduser")
 
控制器
 
func (c *MainController) Adduser() {
	username := c.GetString("username")
	email := c.GetString("email")
	logs.SetLogger(logs.AdapterFile, `{"filename":"logs/user.log","level":7,"maxlines":0,"maxsize":0,"daily":true,"maxdays":10,"color":true}`)
	logs.Info("username:" + username + ",email:" + email)
 
}
 
 
第十五单元 模板语法
 
一.if else end的使用(掌握)
用法:
{{if 条件判断表达式}}
输出内容
{{else}}
输出内容
{{end}}
 
代码示例
控制器层
func (c *MainController) Get() {
	c.Data["Isboy"] = false //向视图传输数据
	c.TplName = "index.tpl" //引入模板
}
视图层
 {{if .Isboy }}
    小帅哥
  {{else}}
    小美女
  {{end}}
 
 
 
二、range … end的使用(掌握)
{{range 数据}}{{.Name}},{{.Email}} {{end}}
 
数据:结构体,map,切片
代码示例
 
控制器层
pages := []struct {
		Num int
	}{{10}, {20}, {30}}
c.Data["Total"] = 100
c.Data["Pages"] = pages
 
视图层
 
 {{range .Pages}}
    {{.Num}} of {{$.Total}}
{{end}}
 
 
三、基本函数使用
 
and
{{and .X .Y .Z}}
{{or .X .Y .Z}}
or 会逐一判断每个参数,将返回第一个非空的参数,否则就返回最后一个参数
or
not 返回输入参数的否定值,if true then false else true
not
urlquery
 
搈制器层
 
func (c *MainController) Get() {
	c.Data["Isboy"] = false //向视图传输数据
 
	sliceData := []string{"one", "two", "three"}
 
	c.Data["sliceData"] = sliceData
	c.Data["X"] = 1
	c.Data["Y"] = 2
	c.Data["Z"] = 1
 
	c.TplName = "index.tpl" //引入模板
}
 
views
 {{range $key,$val:= .sliceData}}
    <div>{{$key}}---{{$val}}</div>
  {{end}}

  {{if compare .X .Y}}
  x=y
  {{else}}
  no
  {{end}}

  {{urlquery "http://beego.me"}}
 
四、模板设置
 
beego.ViewsPath = "模板目录"
conf/app.conf
viewspath = 模板目录
 
 
 
 
总结:
 
重要知识点
1.bee api test3
 
2.bee run
问题:Failed to build the application: go: cannot find main module; see 'go help modules'
解决方案:go mod init
 
3.main.go
 
 
import (
	_ "test3/routers"
 
	"github.com/astaxie/beego"
	"github.com/astaxie/beego/orm" //引入orm
	_ "github.com/go-sql-driver/mysql" //引入mysql驱动模块
)
 
//初始化
func init() {
	//注册mysql驱动信息
	orm.Debug = true //debug开启
	orm.RegisterDataBase("default", "mysql", "root:root@tcp(127.0.0.1:3306)/test3?charset=utf8")
	orm.RunSyncdb("default", false, true)
}
 
4.自动化工具使用
 
bee generate appcode -tables="cates" -driver=mysql -conn="root:root@tcp(127.0.0.1:3306)/test3" -level=3
 
5.swagger文档生成
5.1 swagger压缩包解压到项目目录下
5.2 生成文档
bee run -gendoc=true
访问swagger
 
6.添加日志
 
//日志引擎配置为文件
logs.SetLogger(logs.AdapterFile, `{"filename":"test3.log","daily":true}`)
logs.Info("添加分类成功")
 
7.validation验证
 
 
//验证
		valid := validation.Validation{}
		valid.MaxSize(v.Name, 20, "name").Message("分类名不能超过20个字符")
		valid.MinSize(v.Name, 5, "name").Message("分类名不能少于5个字符")
		//valid.Numeric(v.Sort, "sort").Message("排序字段必须是数字")
		if valid.HasErrors() {
			errMsg := []string{}
			for _, err := range valid.Errors {
				errMsg = append(errMsg, err.Message)
			}
			c.Data["json"] = errMsg
			c.ServeJSON()
			return
		}
 
 
 
8.redis缓存
注意:一定要开启redis服务
 
1. 缓存引擎配置为redis
 
{"key":"collectionName","conn":":6039","dbNum":"0","password":"thePassWord"} 改成6379
 
bm, err := cache.NewCache("redis", `{"key":"test3","conn":"127.0.0.1:6379","dbNum":"0","password":""}`
 
bm.Put("catname", v.Name, 3600*time.Second) //缓存写入
cacheCatname := bm.Get("catname")           //缓存读取
fmt.Println(string(cacheCatname.([]byte)))  //缓存输出
 
 
 
posted @ 2020-08-11 20:50  青春゜如詩  阅读(322)  评论(0)    收藏  举报