0 项目导入
1 在英文路径下新建一个同名的项目,拷贝其他数据到这个文件
bee new 同名项目名
cd 同名项目名
go mod tidy
go get -u -v github.com/astaxie/beego
go get 同名项目名/models
2 拷贝部分的项目文件到新目录
bee run 运行的其他错误,按照提示安装文件
1 后端获取前端传递的数据 post与get
前端get可以使用href
前端post使用表单
get和参数
删除
post和参数
<form name = logon method="post" action="/updateArticle?articleId={{.article.Id}}" enctype="multipart/form-data">
<input type="text" class="input_txt2" name="articleName" >
前端通过表单发送数据, 后端在路由的get或者post的方法中,获取数据
this.GetString():获取字符串类型值
this.GetInt():获取整型值
this.GetFloat:获取浮点型值
…
this.GetFile():获取上传的文件
作用:接收前端传递过来的数据,不管是get请求还是post请求,都能接收。
参数: 是传递数据的key值,一般情况下是form表单中 标签的name属性值
返回值:根据返回类型不同,返回值也不一样,最常用的GetString()只有一个返回值,如果没有取到值
就返回空字符串,其他几个函数会返回一个错误类型。获取的值一般是 标签
里面的value属性值。至于比较特殊的,我们用到的时候给大家做介绍。
知道了获取数据函数,我们就可以获取前端传递过来的数据啦。
<form method="post" action="/addArticle" enctype="multipart/form-data">
<input type="text" class="input_txt2" name="articleName" >
func (c *ArticleController) HandleAddArticle() {
articleName := c.GetString("articleName")
}
2 前端获取后端传递的数据
普通数据
注意前面有个点
c.Data["errmsg"] = "添加数据不完整"
<h1>{{.errmsg}}</h1?
切片数据-循环展示数据
后端
func(this*ArticleController)ShowArticleList(){
//指定表
o := orm.NewOrm()
qs := o.QueryTable("Article")
var articles []models.Article
_,err := qs.All(&articles)
if err != nil{
beego.Info("查询数据错误")
}
//传递数据
this.Data["articles"] = articles
this.TplName = "index.html"
}
前端for循环展示1
{{range $index,$val := .articles}}
<tr>
<td>{{$val.ArtiName}}</td>
<td><a href="/showArticleDetail?articleId={{$val.Id}}">查看详情</a></td>
<td> {{$val.Atime.Format "2006-01-02-15:04:05"}}</td>
<td>{{$val.Acount}}</td>
<td><a href="#" class="dels">删除</a></td>
<td><a href="#">编辑</a></td>
<td>财经新闻</td>
</tr>
{{end}}
前端for循环展示2 (省略了 i n d e x , index, index,val,直接使用属性)
{{range .types}}
<tr>
<td>{{.Id}}</td>
<td>{{.TypeName}}</td>
<td><a href="javascript:;" class="edit">删除</a></td>
</tr>
{{end}}
3 文件上传
1 前端设置enctype属性
<form method="post" action="/addArticle" enctype="multipart/form-data">
2 后端接口
func (c *ArticleController) HandleAddArticle() {
//获取数据
articleName := c.GetString("articleName")
content := c.GetString("content")
//数据校验
if articleName == "" || content == "" {
c.Data["errmsg"] = "添加数据不完整"
c.TplName = "add.html"
return
}
fmt.Println(articleName, content)
//获取上传的文件
file, head, err := c.GetFile("uploadname")
defer file.Close()
if err != nil {
c.Data["errmsg"] = "上传失败"
c.TplName = "add.html"
return
}
//1.文件大小
if head.Size > 5000000 {
c.Data["errmsg"] = "文件太大,请重新上传"
c.TplName = "add.html"
return
}
//2.文件格式
//a.jpg
ext := path.Ext(head.Filename)
if ext != ".jpg" && ext != ".png" && ext != ".jpeg" {
c.Data["errmsg"] = "文件格式错误。请重新上传"
c.TplName = "add.html"
return
}
//3.防止重名,以时间戳命名
timestamp := time.Now().Unix()
timeStr := strconv.Itoa(int(timestamp))
fileName := timeStr + ext
//存储
c.SaveToFile("uploadname", "./static/img/"+fileName)
//3.处理数据
//插入操作
o := orm.NewOrm()
var article models.Article
article.ArtiName = articleName
article.Acontent = content
article.Aimg = "/static/img/" + fileName
o.Insert(&article)
//4.返回页面
c.Redirect("/showArticleList", 302)
}
4 分页
后端分页,
//展示文章列表页
func(this*ArticleController)ShowArticleList(){
//获取数据
//高级查询
//指定表
o := orm.NewOrm()
qs := o.QueryTable("Article")//queryseter
var articles []models.Article
//_,err := qs.All(&articles)
//if err != nil{
// beego.Info("查询数据错误")
//}
//查询总记录数
count,_ := qs.Count()
//获取总页数
pageSize := 2
pageCount := math.Ceil(float64(count) / float64(pageSize))
//获取页码
pageIndex,err:= this.GetInt("pageIndex")
if err != nil{
pageIndex = 1
}
//获取数据
//作用就是获取数据库部分数据,第一个参数,获取几条,第二个参数,从那条数据开始获取,返回值还是querySeter
//起始位置计算
start := (pageIndex - 1)*pageSize
//获取指定数量的数据
qs.Limit(pageSize,start).All(&articles)
//传递数据
this.Data["pageIndex"] = pageIndex
this.Data["pageCount"] = int(pageCount)
this.Data["count"] = count
this.Data["articles"] = articles
this.TplName = "index.html"
}
分页逻辑(首页末页,上一页下一页)
html,
通过视图传递一个参数 | 前面是传递的参数,后一个是视图名,{{显示视图对应函数的返回值}}
通过视图传递多个参数 视图名在前面,空格 后面是参数,{{显示视图对应函数的返回值}}
<ul class="pagenation">
<li><a href="showArticleList?pageIndex=1">首页</a></li>
<li><a href="showArticleList?pageIndex={{.pageIndex | prepage}}">上一页 </a> </li>
<li> <a href="showArticleList?pageIndex={{nextpage .pageIndex .pageCount}}">下一页</a></li>
<li><a href="/showArticleList?pageIndex={{.pageCount}}">末页</a></li>
<li>共{{.count}}条记录/共{{.pageCount}}页/当前{{.pageIndex}}页</li>
</ul>
main.go,通过添加视图,并绑定视图与函数的关系,来执行函数
func main() {
//绑定视图和函数
beego.AddFuncMap("prepage", ShowPrePage)
beego.AddFuncMap("nextpage", ShowNextPage)
beego.Run()
}
//上一页
func ShowPrePage(pageIndex int) int {
if pageIndex == 1 {
return pageIndex
}
var pageIndex2 = pageIndex - 1
return pageIndex2
}
//下一页
func ShowNextPage(pageIndex int, pageCount int) int {
if pageIndex == pageCount {
return pageIndex
}
var pageIndex2 = pageIndex + 1
return pageIndex2
}
5 弹窗提示
$(“选择器”)
<head>
<script type="text/javascript">
window.onload = function (ev) {
$(".dels").click(function () {
if(!confirm("是否确认删除")){return false}
})
}
</script>
</head>
6 多表相关(数据定义)
1.一对多(外键)
rel(fk)和reverse(many)成对出现,表示一对多的关系,一是变量,多是切片,类型是对应的表名
type Article struct {
Id int `orm:"pk;auto"`
//多
ArticleType *ArticleType `orm:"rel(fk)"`
}
// 类型表
type ArticleType struct {
Id int
TypeName string `orm:"size(20)"`
// 1
Articles []*Article `orm:"reverse(many)"`
}
多对多(创建关系表)
reverse(many)和rel(m2m)成对出现表示多对多关系,都是使用切片定义,类型是表名,本质是创建了关系表
// 定义一个结构体
type User struct {
Id int
Articles []*Article `orm:"reverse(many)"`
}
type Article struct {
Id int `orm:"pk;auto"`
ArtiName string `orm:"size(20)"`
Users []*User `orm:"rel(m2m)"`
}
6 多表相关(数据操作)
1.一对多(插入操作)
只需要在文章表插入类型对象即可。代码如下:
o := orm.NewOrm()
//多
article := models.Article{}
//一
artiType := models.ArticleType{Id:id}
//查询一的外键
o.Read(&artiType)
//多赋值
article.ArticleType = &artiType
//多插入
o.Insert(&article)
2.一对多(查询操作)
当需要在当前表查询其他表的数据时,使用这种方式.,但是当表没有关联表的数据时,不会找到记录
比如此处,关联文章类型表,来查询文章表的数据.没有文章类型的数据是找不到的,因为没有外键.
ORM做多表查询的时候默认是惰性查询,即不明确指出来要做多表查询,即便是两个表之间存在关系,ORM也不会给两个表做关联。指定多表查询的函数是RelatedSel()。参数是要关联的表名,可以有多个。如果没有关联,那么就是单表查询.代码如下:
o.QueryTable("要查询的表-多").RelatedSel("要关联的表-一").Count()
count,err = o.QueryTable("Article").RelatedSel("ArticleType").Count()
如果关联表的那个字段没有值,那么数据查不到
根据选中的类型查询相应类型文章
通过Filter(“表名__表字段”, 表字段值)进行过滤,相当于where
//根据选中的类型查询相应类型文章
typeName := this.GetString("select")
qs.Limit(pageSize, start).RelatedSel("ArticleType").Filter("ArticleType__TypeName", typeName).All(&articles)
7 beego中Session和Cookie
Cookie
用来一定时间的保存用户数据,数据存储在客户端(网站的客户端就是浏览器),启用的时候能设置Cookie的有效时间,当时间截至的时候,Cookie失效.
Beego中对Cookie的存取删
Beego把数据存储到Cookie中代码如下:
this.Ctx.SetCookie(key,value,time)//第一个参数是Cookie的key值,第二个参数是Cookie的value值,第三个参数是设置的Cookie的有效时间。
取Cookie的代码如下:
this.Ctx.GetCookie(key)//参数是Cookie的key值,返回值是对应的value值。当没有对应的Cookie或者Cookie已失效,返回空字符串
删除Cookie的代码如下:
this.Ctx.SetCookie(key,value,0)//第一个参数是Cookie的key值,第二个参数任意值,第三个参数把Cookie的值设置为小于0,就马上失效。
Session
也是用来一定时间的保存用户数据,不过数据存储在服务器,Beego启用Sesssion的时候需要在配置文件中开启Session功能。在Beego使用中,一般不设置Session的时间,当浏览器关闭的时候,Session失效。
**Beego中对Session的存取 **
如果想要在项目中使用Session功能,需要先在配置文件中设置Sessionon=true
Beego存储Session的代码:
this.SetSession(key,value)//两个参数,一个是Session的key,第二个是Session的Value
获取Session的代码如下:
this.GetSession(key)//参数是Session的key值,返回值是Session对应的value值,类型是interface{}
删除Session的代码如下:
this.DelSession(key)//参数是Session的key值
我们通过表格来分析他们的不同
不同点 | Cookie | Session |
---|---|---|
数据存储位置 | 客户端 | 服务器 |
数据安全性(相比较而言) | 低 | 高 |
生命周期 | 随着设置时间的结束,生命周期结束 | 当浏览器关闭的时候,生命周期结束 |
适用场景 | 对安全性要求不高的,需要存储时间较长的数据 | 安全性要求搞,不需要长期存储的数据 |