beego框架总结

0、为什么选择beego框架?

Beego框架是go语言开发的web框架(有go语言基础,能很快上手)go语言的web框架:beego,gin,echo等等,那为什么我们选择beego呢?第一,beego是中国人开发的,开发文档比较详细,beego官网网址: https://beego.me/ 。第二,现在公司里面用beego的也比较多,比如今日头条,百度云盘,腾讯,阿里等。

Beego不足之处:

BeegoMVC架构。大多数代码位于Controller中,显得Controller特别臃肿。采用多文件处理(将不同模块的Controller分开处理)。对fastDFS、Redis支持度不够,可以调用接口实现或导包实现("github.com/weilaihui/fdfs_client";"github.com/gomodule/redigo/redis")。

 

1、MVC设计模式

什么是MVC?

 MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。MVC被独特的发展起来用于映射传统的输入、处理和输出功能在一个逻辑的图形化用户界面的结构中。

 

Model(模型)

是应用程序中用于处理应用程序数据逻辑的部分。通常模型对象负责在数据库中存取数据。

View(视图)

是应用程序中处理数据显示的部分。通常视图是依据模型数据创建的。

Controller(控制器)

是应用程序中处理用户交互的部分。通常控制器负责从视图读取数据,控制用户输入,并向模型发送数据。

 

MVC是一个框架模式,它强制性的使应用程序的输入、处理和输出分开。使用MVC应用程序被分成三个核心部件:模型、视图、控制器。它们各自处理自己的任务。

设计模式:

随着Web应用的商业逻辑包含逐渐复杂的公式分析计算、决策支持等,使客户机越来越不堪重负,因此将系统的商业分离出来。单独形成一部分,这样三层结构产生了。

其中‘层’是逻辑上的划分。

三层体系结构是将整个系统划分为三层结构:

(1)表现层(Presentation layer):包含表示代码、用户交互GUI、数据验证。

该层用于向客户端用户提供GUI交互,它允许用户在显示系统中输入和编辑数据,同时系统提供数据验证功能。

(2)业务逻辑层(Business layer):包含业务规则处理代码,即程序中与业务相关专业算法、业务政策等等。

该层用于执行业务流程和制订数据的业务规则。业务逻辑层主要面向业务应用,为表示层提供业务服务。

(3)数据持久层(Persistence layer):包含数据处理代码和数据存储代码。数据持久层主要包括数据存取服务,负责与数据库管理系统(如数据库)之间的通信。

三个层次的每一层在处理程序上有各自明确的任务,在功能实现上有清晰的区分,各层与其余层分离,但各层之间存有通信接口。

采用三层软件设计架构后,软件系统在可扩展性和可复用性方面得到极大提高,在资源分配策略设计合理运用的同时,软件的性能指标也得到提升,系统的安全性和易管东北理性也得到改善。

三层体系结构对Web应用的软件架构产生很大影响,促进了基于组件的设计思想,产生了许多开发Web层次框架的实现技术。较之两级结构来说,三层结构修改和维护上更加方便。

目前开发B/S结构的Web应用系统广泛采用这种三层体系结构。

2、Redis

是一种高性能的Key-Value数据库

NoSQL介绍  mysql  sqlite  sqlserver Oracle

NoSQL:一类新出现的数据库(not only sql),它的特点:

1.不支持SQL语法

2.存储结构跟传统关系型数据库中的那种关系表完全不同,nosql中存储的数据都是Key-Value形式

3.NoSQL的世界中没有一种通用的语言,每种nosql数据库都有自己的api和语法,以及擅长的业务场景

  • NoSQL中的产品种类相当多

Mongodb

Redis

Hbase hadoop

Cassandra hadoop

NoSQL和SQL数据库的比较:

  • 适用场景不同:sql数据库适合用于关系特别复杂的数据查询场景,nosql反之
  • 两者在不断地取长补短,呈现融合趋势

Redis简介

  • Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。从2010315日起,Redis的开发工作由VMware主持。从20135月开始,Redis的开发由Pivotal赞助。
  • Redis NoSQL技术阵营中的一员,它通过多种键值数据类型来适应不同场景下的存储需求,借助一些高层级的接口使用其可以胜任,如缓存、队列系统的不同角色

Redis特性

  • Redis 与其他 key - value 缓存产品有以下三个特点:
  • Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。
  • Redis不仅仅支持简单的key-value类型的数据,同时还提供string listsetzsethash等数据结构的存储。
  • Redis支持数据的备份,即master-slave模式的数据备份。

Redis 优势

  • 性能极高 – Redis能读的速度是110000/s,写的速度是81000/s
  • 丰富的数据类型 – Redis支持二进制案例的 Strings, Lists, Hashes, Sets Ordered Sets 数据类型操作。
  • 原子 – Redis的所有操作都是原子性的,同时Redis还支持对几个操作全并后的原子性执行。
  • 丰富的特性 – Redis还支持 publish/subscribe, 通知, key 过期等等特性。redis应用场景
  • 用来做缓存(ehcache/memcached)——redis的所有数据是放在内存中的(内存数据库)
  • 可以在某些特定应用场景下替代传统数据库——比如社交类的应用
  • 在一些大型系统中,巧妙地实现一些特定的功能:session共享、购物车
  • 只要你有丰富的想象力,redis可以用在可以给你无限的惊喜…….

中文官网Redis.cn

3、利用fastDFS存储图片

什么是FastDFS

FastDFS 是用 c 语言编写的一款开源的分布式文件系统。FastDFS 为互联网量身定制, 充分考虑了冗余备份、负载均衡、线性扩容等机制,并注重高可用、高性能等指标,使用 FastDFS 很容易搭建一套高性能的文件服务器集群提供文件上传、下载等服务。

优点:

FastDFS 架构包括 Tracker server 和 Storage server。客户端请求 Tracker server 进行文 件上传、下载,通过 Tracker server 调度最终由 Storage server 完成文件上传和下载。

Tracker server 作用是负载均衡和调度,通过 Tracker server 在文件上传时可以根据一些 方法找到 Storage server 提供文件上传服务。可以将 tracker 称为追踪服务器或调度服务 器。

Storage server 作用是文件存储,客户端上传的文件最终存储在 Storage 服务器上, Storageserver 没有实现自己的文件系统而是利用操作系统 的文件系统来管理文件。可以将 storage 称为存储服务器。

服务端两个角色:

Tracker:管理集群,tracker 也可以实现集群。每个 tracker 节点地位平等。收集 Storage 集群的状态。

Storage:实际保存文件

Storage 分为多个组,每个组之间保存的文件是不同的。每 个组内部可以有多个成员,组成员内部保存的内容是一样的,组成员的地位是一致的,没有 主从的概念。

文件上传流程

客户端上传文件后存储服务器将文件 ID 返回给客户端,此文件 ID 用于以后访问该文 件的索引信息。文件索引信息包括:组名,虚拟磁盘路径,数据两级目录,文件名。

组名: 文件上传后所在的 storage 组名称,在文件上传成功后有 storage 服务器返回, 需要客户端自行保存。

虚拟磁盘路径: storage 配置的虚拟路径,与磁盘选项 store_path*对应。如果配置了 store_path0 则是 M00,如果配置了 store_path1 则是 M01,以此类推。

数据两级目录 :storage 服务器在每个虚拟磁盘路径下创建的两级目录,用于存储数据 文件。

文件名 :与文件上传时不同。是由存储服务器根据特定信息生成,文件名包含:源存储 服务器 IP 地址、文件创建时间戳、文件大小、随机数和文件拓展名等信息。

文件下载流程

简易FastDFS架构

4、beego数据操作

(1)ORM使用

对象关系映射(英语:(Object Relational Mapping,简称ORM,或O/RM,或O/R mapping),是一种程序技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换  。从效果上说,它其实是创建了一个可在编程语言里使用的--“虚拟对象数据库”。

官网:https://beego.me/docs/mvc/model/orm.md

表关系如下:

type Post struct {
    Id    int
    Title string
    User  *User  `orm:"rel(fk)"`
    Tags  []*Tag `orm:"rel(m2m)"`
}
type Post struct {
    Id    int
    Title string
    User  *User  `orm:"rel(fk)"`
    Tags  []*Tag `orm:"rel(m2m)"`
}
type Tag struct {
    Id    int
    Name  string
    Posts []*Post `orm:"reverse(many)"`
}

QueryTable(interface{}) QuerySeter:传入表名,或者 Model 对象,返回一个 QuerySeter

QueryM2M(interface{}, string) QueryM2Mer:多对多关系操作

o := orm.NewOrm()
var qs QuerySeter
qs = o.QueryTable("user")
// 如果表没有定义过,会立刻 panic
创建一个 QueryM2Mer 对象

o := orm.NewOrm()
post := Post{Id: 1}
m2m := o.QueryM2M(&post, "Tags")
// 第一个参数的对象,主键必须有值
// 第二个参数为对象需要操作的 M2M 字段
// QueryM2Mer 的 api 将作用于 Id 为 1 的 Post

(2)高级查询

官网链接:https://beego.me/docs/mvc/model/query.md

RelatedSel(…interface{}) QuerySeter:关系查询

a、一对一关系

o := orm.NewOrm()
user := User{Id: 1}

err := o.Read(&user)

b、一对多关系查询

 type Address struct { //地址表
    Id int
    User *User `orm:"rel(fk)"`     //用户ID
 
}
type User struct{ //用户表
	Id 			int
	Name 		string`orm:"size(20);unique"` 		//用户名
	Address		[]*Address `orm:"reverse(many)"`
	

}

 //获取所有地址(一对多查询)
var address []models.Address
o.QueryTable("Address").RelatedSel("User").Filter("User__Name",user.Name).All(&address)

type IndexTypeGoodsBanner struct {//首页分类商品展示表
	Id 				int
	GoodsType 		*GoodsType 	`orm:"rel(fk)"`			//商品类型
	GoodsSKU  		*GoodsSKU  	`orm:"rel(fk)"`			//商品sku
	DisplayType 	int   		`orm:"default(1)"`		//展示类型 0代表文字,1代表图片
	Index 			int   		`orm:"default(0)"`		//展示顺序
}

type GoodsType struct{//商品类型表
	Id int
	Name string			//种类名称
	GoodsSKU []*GoodsSKU `orm:"reverse(many)"`
	IndexTypeGoodsBanner  []*IndexTypeGoodsBanner  `orm:"reverse(many)"`
}


type GoodsSKU struct { //商品SKU表
	Id int
	Goods     *Goods 	 `orm:"rel(fk)"` //商品SPU
	GoodsType *GoodsType `orm:"rel(fk)"`  //商品所属种类
	IndexTypeGoodsBanner []*IndexTypeGoodsBanner  `orm:"reverse(many)"`
}


//一个表和另外两个表关联查询
var text []models.IndexTypeGoodsBanner  //显示商品文字
var image []models.IndexTypeGoodsBanner //显示商品图片

//获取商品文字数据
o.QueryTable("IndexTypeGoodsBanner").RelatedSel("GoodsType", "GoodsSKU").OrderBy("Index").Filter("GoodsType", value["type"]).Filter("DisplayType", 0).All(&text)
		//获取商品图片数据
o.QueryTable("IndexTypeGoodsBanner").RelatedSel("GoodsType", "GoodsSKU").OrderBy("Index").Filter("GoodsType", value["type"]).Filter("DisplayType", 1).All(&image)

c、多对多关系查询(两层循环执行):

var goodType []models.GoodsType
	o := orm.NewOrm()
	o.QueryTable("GoodsType").All(&goodType)

goods := make([]map[string]interface{}, len(goodType))
	for index, value := range goodType {
		temp := make(map[string]interface{})
		temp["type"] = value
		goods[index] = temp
	}

d、更新操作:

o.QueryTable("GoodsSKU").Filter("Id", good.Id).Filter("Stock", preCount).Update(orm.Params{"Stock": good.Stock, "Sales": good.Sales})

猜你喜欢

转载自blog.csdn.net/weixin_42117918/article/details/83416244