既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Go语言开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
fail:function (data) {
}
})
}
2.4.1 form方式上传
- 前端
前端:
上传文件:
注意:
这里必须设置enctype=“multipart/form-data”,不然浏览器不会传送文件
- 后端
type Upload struct {
beego.Controller
}
func (u *Upload)Get() {
u.TplName = “upload_file.html”
}
func (u *Upload)Post() {
// 获取上传的文件
f,h,err := u.GetFile(“upload_file”)
if err != nil {
fmt.Println(err)
return
}
defer f.Close()
// 生成时间戳,防止重名
timeUnix:=time.Now().Unix() // int64类型
time_str := strconv.FormatInt(timeUnix,10) // 将int64转为字符串 convert:转换
// 保存获取到的文件
err1 := u.SaveToFile(“upload_file”,“static/upload/”+time_str+h.Filename) // 这里必须有这个路径才会保存成功, 否则报错:The system cannot find the path specified
if err1 != nil{
fmt.Println(err1)
}
u.TplName = “index.tpl”
}
注意:
相同文件名的文件会被后面上传的覆盖,可以使用时间戳重命名文件
二、ajax方式上传
- 前端
-
processData 默认为true,当设置为true的时候,jquery ajax 提交的时候不会序列化 data,而是直接使用data
-
contentType: false 不使用默认的application/x-www-form-urlencoded这种contentType
-
分界符:目的是防止上传文件中出现分界符导致服务器无法正确识别文件起始位置
-
ajax 中 contentType 设置为 false 是为了避免 JQuery 对其操作,从而失去分界符
背景:假如前端或者提供的接口必须以指定的格式传输
json格式:会设置 content-type 为 application/json
type TestController struct {
beego.Controller
}
type Person struct {
Id int
Name string
Gender string
}
func (g *TestController)Get() {
test_data := Person{Id:123,Name:“zhiliao”,Gender:“男”}
g.Data[“json”] = &test_data -----这里必须叫json,因为ServeJSON()解析json变量的
fmt.Println(test_data)
g.ServeJSON()
//g.TplName = “test.html”
}
xml格式:会设置 content-type 为 application/xml
test_data := Person{Id:123,Name:“zhiliao”,Gender:“男”}
g.Data[“xml”] = &test_data -----这里必须叫xml,同上
g.ServeXML()
jsonp格式:会设置 content-type 为 application/javascript
test_data := Person{Id:123,Name:“zhiliao”,Gender:“男”}
g.Data[“jsonp”] = &test_data -----这里必须叫jsonp,同上
g.ServeJSONP()
yaml格式:会以文件传输的方式,yaml就是键值对
test_data := Person{Id:123,Name:“zhiliao”,Gender:“男”}
g.Data[“yaml”] = &test_data
g.ServeYAML()
yaml格式:
student:
-
name : “zhiliao”
-
age : 18
teacher:
- name : “laowang”
-age : 38
addr: “市区”
说明:
-
大小写敏感
-
使用缩进表示层级关系
-
缩进不允许使用tab,只允许空格
-
缩进的空格数不重要,只要相同层级的元素左对齐即可
-
'#'表示注释
-
以 - 开头的行表示构成一个数组,支持多维数组
===================================================================
3.1.1 基本语法
-
使用
.
来访问当前位置的上下文 -
使用
$
来引用当前模板根级的上下文 -
使用
$.
引用模板中的根级上下文
3.1.2其他常用模板语法
- 支持go语言的符号,这里只是符号的支持
① 字符串:{ { “zhiliao ” } }
② 原始字符串:{ { `zhiliao` } } 不会转义
③ 字节类型:{ { ’ a’ } } -->97 ascll码对应表: http://ascii.911cha.com/
④ nil:{ { print nil } } { {nil } }只有nil会报错:nil is not a command
-
if:判断
-
range:循环
注:range也支持else,表示空数组的时候执行
- template:对于模板的分模块处理很有用处,引入另一个模板文件
{{template “bottom.html” .}}
注意:如果引入的文件也需要获取动态数据,那{ {template “bottom.html” .} }中必须使用.访问当前位置的上下文
- and
{ {and .X .Y .Z} }
只要有一个为空,则整体为空,如果都不为空,则返回最后一个
- or
{ {or .X .Y .Z} }
只要有一个不为空,则返回第一个不为空的,否则返回空
- index:读取指定类型对应下标的值
获取
后端:
this.Data[“data_map”] = map[string]string{“name”: “Beego”}
this.Data[“arrs”] = []int{1,2,3,4,5}
前端:
{{index .data_map “name”}}
{{index .arrs 1}}
- len:返回对应类型的长度
{ { .Content|len } }
- not:返回输入参数的否定值
{{not .is_ok }}
6.eq / ne / lt / le / gt / ge
-
eq:等于 equls
-
ne:不等于
-
lt:小于 less
-
le:小于等于 区别于lte
-
gt:大于 greater
-
ge:大于等于 区别于gte
- 内置模板函数
1.date 格式化时间
{{date .T “Y-m-d H:i:s”}}
- compare 比较
{{compare ‘a’ 97}}
- substr 截取字符串
{{substr “我是中国人” 0 4}}
- map_get 获取map的指定key值
{{ map_get .m “a” }}
- url_for
{{urlfor “TestController.List”}}
第一步:定义函数
func hello(in string)(out string){
out = in + “world”
return
}
第二步:AddFuncMap
// 在beego.Run()之前
beego.AddFuncMap(“hi”,helle)
第三步:前端使用
{{“hello world” | hi}}
=========================================================================
4.1.1 读取配置
beego.AppConfig.String(“mysqluser”)
4.2.2 引入其他配置文件
app.conf是主配置文件。其他的配置文件需要再app.conf中引入
include “mysql_server.conf”
4.3.3 常用的配置
-
ViewsPath:模板路径,默认值是 views。
-
StaticDir:静态文件目录设置,默认是static
-
sessionon:session 是否开启,默认是 false
-
httpport:监听端口
-
EnableXSRF:EnableXSRF
-
XSRFExpire:XSRF 过期时间,默认值是 0,不过期。
-
MaxMemory:文件上传默认内存缓存大小,默认值是1 << 26(64M)。
-
RunMode:应用的运行模式,可选值为prod,dev或者test. 默认是dev, 为开发模式
4.2.1 固定路由
一个固定的路由,一个控制器,然后根据用户请求方法不同请求控制器中对应的方法
beego.Router(“/hello”, &controllers_user.Hello{})
4.2.2 正则路由
beego.Router(“/api/?:id”, &controllers.RController{})
beego.Router(“/api/?🆔int”, &controllers.RController{})
:id([0-9]+) 或者 :id([\d]+) 或者 🆔int
:username([\w]+) 或者 :username:string
4.2.3 自动路由
注册路由的时候不需要指定url,只需要注册控制器即可
beego.AutoRouter(&controllers.UserController{})
规则:
/控制器名/方法名/后面的都是参数。。。
如:/user/get/123/456
4.2.4 自定义路由
注册路由的时候可以指定第三个参数,这个参数就是用来自定义路由的
用法: method :函数名
post:Login post请求的时候访问Login函数
get:User get请求的时候访问User函数
*:LoginOut 所有的请求方法都访问LoginOut函数
需要登录才能访问的
/cms/user/add
/cms/user/list
/cms/user/edit
/cms/book/add
不需要登录可以访问:
/
/login
/register
beego.InsertFilter(pattern string, position int, filter FilterFunc, params …bool)
-
第一个参数表示过滤的路由规则,支持通配符
-
第二个参数就是过滤器的位置,beego支持的有5种
-
BeforeStatic 静态地址之前
-
BeforeRouter 寻找路由之前
-
BeforeExec 找到路由之后,开始执行相应的 Controller 之前
-
AfterExec 执行完 Controller 逻辑之后执行的过滤器
-
FinishRouter 执行完逻辑之后执行的过滤器
-
第三个参数为执行的函数
-
func(*context.Context) 参数必须是context.Context , context是beego包下的
-
其他参数:使用默认得到true即可
示例:
func main() {
// 过滤器
beego.InsertFilter(“/*”, beego.BeforeRouter, controllers.LoginSpider1Filter)
beego.Run()
}
func LoginSpider1Filter(ctx *context.Context) {
// 获取session
id := ctx.Input.Session(“spider1_uid”)
if id == nil { // 说明未登录
ctx.Redirect(302,“/main/spider1/to_login”)
// 路由反转:beego.URLFor(“TestController.Get”)
}
}
注意:使用 session 的 Filter 必须在 BeforeStatic 之后才能获取,因为 session 没有在这之前初始化。
4.4.1 安装
go get github.com/astaxie/beego/validation
4.4.2 使用
结构体定义tag
-
验证函数写在 “valid” tag 的标签里
-
各个函数之间用分号 “;” 分隔,分号后面可以有空格
-
参数用括号 “()” 括起来,多个参数之间用逗号 “,” 分开,逗号后面可以有空格
-
正则函数(Match)的匹配模式用两斜杠 “/” 括起来
-
各个函数的结果的 key 值为字段名.验证函数名
type LoginParams struct {
Name string valid:“Required”
Age int valid:“Required;MinSize(2)”
Addr string valid:“Required”
}
func (l *LoginController) Post() {
valid := validation.Validation{}
// 解析到结构体
params := LoginParams{}
if err := l.ParseForm(¶ms); err != nil {
//handle error
return
}
//重写错误信息:validation.SetDefaultMessage(map)
var messages = map[string]string{
“Required”: “不能为空”,
“MinSize”: “最短长度为 %d”,
“Length”: “长度必须为 %d”,
“Numeric”: “必须是有效的数字”,
“Email”: “必须是有效的电子邮件地址”,
“Mobile”: “必须是有效的手机号码”,
}
validation.SetDefaultMessage(messages)
// 校验
b, err := valid.Valid(¶ms)
// 验证StructTag 是否正确
if err != nil {
fmt.Println(err)
}
if !b {
// 验证没通过,则b为false
for _, err := range valid.Errors {
fmt.Println(err.Key, err.Message)
message := err.Key + err.Message
l.Ctx.WriteString(message)
}
}
}
4.5.1 什么是session?
-
Session是在_无状态_的HTTP协议下,服务端记录用户状态时用于标识具体用户的机制
-
它是在服务端保存的用来跟踪用户的状态的数据结构,可以保存在文件、数据库或者集群中
-
在浏览器关闭后这次的Session就消失了,下次打开就不再拥有这个Session。其实并不是Session消失了,而是Session ID变了,
4.5.2 什么是cookie?
-
Cookie是客户端保存用户信息的一种机制,用来记录用户的一些信息
-
每次HTTP请求时,客户端都会发送相应的Cookie信息到服务端。它的过期时间可以任意设置,如果你不主动清除它,在很长一段时间里面都可以保留着,即便这之间你把电脑关机了。
-
每次客户端发请求的时候会自动携带该域名下的Cookie,不用域名间的Cookie是不能共享的
4.5.3 session和cookie:
-
Cookie 在客户端(浏览器),Session 在服务器端。
-
Cookie的安全性一般,他人可通过分析存放在本地的Cookie并进行Cookie欺骗。在安全性第一的前提下,选择Session更优。重要交互信息比如权限等就要放在Session中,一般的信息记录放Cookie就好了。
-
单个Cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个Cookie。
-
Session 可以放在 文件、数据库或内存中
-
用户验证这种场合一般会用 Session。因此,维持一个会话的核心就是客户端的唯一标识,即Session ID。
-
Session 的运行依赖Session ID,而 Session ID 是存在 Cookie 中的,也就是说,如果浏览器禁用了 Cookie,Session 也会失效(但是可以通过其它方式实现,比如在 url 中传递 Session ID)
4.5.4 beego中使用session:
-
开启session
-
main.go中开启:
-
beego.BConfig.WebConfig.Session.SessionOn = true
-
配置文件中开启:
-
sessionon = true
-
使用sessio
-
设置session
-
SetSession(name string, value interface{})
-
this.SetSession(“username”, “zhiliao”)
-
获取session
-
GetSession(name string) interface{}
-
this.GetSession(“username”)
-
删除session
-
this.DelSession(name string)
-
在过滤器中获取session
-
ctx.Input.Session(“user_name”)
-
关于session的一些其他配置
-
设置是否开启 Session
-
beego.BConfig.WebConfig.Session.SessionOn
-
默认为false
-
设置 Session 过期的时间
-
beego.BConfig.WebConfig.Session.SessionGCMaxLifetime
-
默认值是 3600 秒
-
设置 cookie 的过期时间
-
beego.BConfig.WebConfig.Session.SessionCookieLifeTime
-
设置sessionid加密算法
-
beego.BConfig.WebConfig.Session.SessionHashFunc
-
默认值为 sha1
-
修改sessionkey
-
beego.BConfig.WebConfig.Session.SessionHashKey
-
默认的 key 是 beegoserversessionkey,建议在使用的时候修改该参数
-
设置 cookies 的名字
-
beego.BConfig.WebConfig.Session.SessionName
-
Session 默认是保存在用户的浏览器 cookies 里面的,默认名是 beegosessionID,配置文件对应的参数名是:sessionname。
====================================================================
5.1.1 mysql安装
- 用户名和密码的配置
5.1.2 navicat安装
5.1.3 beego中使用
-
安装:
-
go get github.com/astaxie/beego/orm
-
go get github.com/go-sql-driver/mysql
-
连接数据库:
-
orm.RegisterDriver(“mysql”, orm.DRMySQL)
-
orm.RegisterDataBase(“default”, “mysql”, “用户名:密码@tcp(IP:端口号)/数据库?charset=utf8”, 30)
-
参数一:数据库的别名,用来在 ORM 中切换数据库使用
-
参数二:驱动名称
-
参数三:对应的链接字符串
-
参数四(可选):设置最大空闲连接
-
或根据数据库别名设置:orm.SetMaxIdleConns(“default”, 30)
-
参数五(可选):设置最大数据库连接
-
或根据数据库别名设置: orm.SetMaxOpenConns(“default”, 30)
-
注册模型
-
在init函数中:orm.RegisterModel(new(Article)),只有注册了模型才可以使用
-
创建表
-
在数据库中操作创建表即可,后面会讲自动迁移表
-
时区设置:
-
orm.DefaultTimeLoc = time.UTC // 设置为 UTC 时间
-
ORM 在进行 RegisterDataBase 的同时,会获取数据库使用的时区,然后在 time.Time 类型存取时做相应转换,以匹配时间系统,从而保证时间不会出错
-
示例代码
-
首先创建好数据库和表,表对应结构体中的属性
-
app.conf链接信息配置:
dbhost = 127.0.0.1
dbuser = root
dbpassword = root
dbport = 3306
db = user
main.go中初始化链接:
-
orm.RegisterDriver(“mysql”, orm.DRMySQL)
-
orm.RegisterDataBase(“default”, “mysql”, “root:root@/orm_test?charset=utf8”)
“github.com/astaxie/beego/orm”
_ “github.com/go-sql-driver/mysql”
func init() {
// 读取配置信息
dbhost := beego.AppConfig.String(“dbhost”)
dbport := beego.AppConfig.String(“dbport”)
dbuser := beego.AppConfig.String(“dbuser”)
dbpassword := beego.AppConfig.String(“dbpassword”)
db := beego.AppConfig.String(“db”)
//注册mysql Driver
orm.RegisterDriver(“mysql”, orm.DRMySQL)
//构造conn连接
//用户名:密码@tcp(url地址)/数据库
conn := dbuser + “:” + dbpassword + “@tcp(” + dbhost + “:” + dbport + “)/” + db + “?charset=utf8”
//注册数据库连接
orm.RegisterDataBase(“default”, “mysql”, conn)
fmt.Printf(“数据库连接成功!%s\n”, conn)
}
模型结构体:
注意:结构体的字段名首字母必须大写
type Article struct {
Id int
Name string
Author string
}
func init(){
orm.RegisterModel(new(Article))
}
增加数据:
o := orm.NewOrm()
o.Using(“default”) // default可以不用using
newStudent := Student{Name:“zhiliao”,Age:18,Gender:“男”}
//新增数据
id, err :=o.Insert(&newStudent) // 返回添加的数据id以及错误信息
注意:
- ORM 必须注册一个别名为 default 的数据库,作为默认使用
用作数据库数据转换和自动建表
5.2.1 模型名和表名映射
- 模型名和表名的映射规则:除了开头的大写字母以外,遇到大写会增加 _,原名称中的下划线保留。
① Article -> article
② AuthUser -> auth_user
③ Auth_User -> auth__user 两个下划线
④DB_AuthUser -> d_b__auth_user
- 自定义表名
type User struct {
Id int
Name string
}
func (u *User) TableName() string {
return “auth_user”
}
5.2.2 设置参数:使用structtag
-
忽略字段structtag:`orm:“-”`
-
pk设置为主键,适用于自定义其他类型为主键
-
null:Name string `orm:“null”`
-
auto:自增长
Id int orm:"pk;auto"
- index:索引
Name string orm:"index"
索引的作用:优化查询,相当于图书的目录
- unique
Name string orm:"unique"
- column
Name string orm:"column(user_name)"
- size:对string起作用
Title string orm:"size(60)"
- digits / decimals 4 2 12.21
Money float64 orm:"digits(12);decimals(4)"
总长度12,小数点后有4位小数
- auto_now / auto_now_add
Created time.Time orm:"auto_now_add;type(datetime)"
Updated time.Time orm:"auto_now;type(datetime)"
auto_now 每次 model 保存时都会对时间自动更新
auto_now_add 第一次保存时才设置时间
- type:日期还是时间
Created time.Time orm:"auto_now_add;type(date)"
Created time.Time orm:"auto_now_add;type(datetime)"
- default
Gender float64 orm:"default(0)"
- description
修改源码:cmd_utils.go的 getColumnAddQuery()最后加:fi.description,
Name string orm:"description(这是标签名称)"
5.2.3 表关系
- 一对一
① User模型中: Profile *Profile `orm:“rel(one)”` 正向关系,有外键字段
② Profile模型中: User *User `orm:“reverse(one)”` 反向关系,只是关系,没有外键
- 一对多
① article模型中:User *User `orm:“rel(fk)”` 正向关系,有外键,外键在多的一方
② user模型中:Articles []*Articles `orm:“reverse(many)” 反向关系,没有外键
一对多,外键在多的一方
- 多对多
① post模型中:Tags []*Tag `orm:“rel(m2m)”` 正向关系,没有外键
② tag模型中:Posts []*Post `orm:“reverse(many)”` 反向关系,没有外键
前提:注册模型:RegisterModel
5.3.1 使用QueryTable
o := orm.NewOrm()
qs := o.QueryTable(“user”) 表名作为参数
qs := o.QueryTable(new(User)) 也可以直接使用对象作为表名
返回的是QuerySeter
5.3.2 exper表达式的使用:两个下换线
- exact / iexact:等于,默认值,大小写敏感 / 不敏感
qs.Filter(“name__exact”,“Zhiliao”).One(&stu)
- contains / icontains:包含,大小写敏感 / 不敏感
qs.Filter(“name__contains”,“Zhil”).One(&stu)
- gt / gte:大于/大于等于
qs.Filter(“age__gt”,18).One(&stu)
- lt / lte:小于/小于等于
qs.Filter(“age__lt”,18).One(&stu)
- startswith / istartswith:以…起始,大小写敏感 / 不敏感
qs.Filter(“name__startswith”,“Zh”).One(&stu)
qs.Filter(“name__istartswith”,“Zh”).One(&stu)
- endswith / iendswith:以…结束,大小写敏感 / 不敏感
qs.Filter(“name__endswith”,“Liao”).One(&stu)
qs.Filter(“name__iendswith”,“Liao”).One(&stu)
- in:在某个范围中,值为不定长参数
qs.Filter(“age__in”,12,13,16,19).One(&stu)
- isnull:为空,值为 true / false
qs.Filter(“gender__isnull”,true).One(&stu)
查看orm执行的sql语句:
-
只作用于当前的模型:当前模型的init中orm.Debug = true
-
作用于所有模型:beego.Run()前面设置orm.Debug = true
One:一条数据
-
qs.Filter(“name__exact”,“Zhiliao”).One(&stu)
-
指定显示的字段
-
qs.Filter(“name__exact”,“Zhiliao”).One(&stu,“name”,“age”)
Filter:包含条件
-
多个 Filter 之间使用 AND 连接
-
qs.Filter(“profile__isnull”, true).Filter(“name”, “slene”)
-
类sql: WHERE NOT profile_id IS NULL AND name = ‘slene’
All:所有数据
-
返回对应的结果集对象
-
默认最大行数为 1000
-
user_arr := []models.UserStruct{}
-
qs.Filter(“name__exact”,“Zhiliao”).All(&user_arr)
-
指定显示的字段
-
qs.Filter(“name__exact”,“Zhiliao”).All(&user_arr,“name”,“age”)
Exclude:排除条件
-
Exclude 之间使用 AND 连接
-
使用 NOT 排除条件
-
qs.Exclude(“profile__isnull”, true).Filter(“name”, “slene”)
Limit:限制最大返回数据行数
-
第二个可选参数可以设置Offset,意思从什么位置开始查询
-
qs.Limit(10, 20)
-
LIMIT 10 OFFSET 20 注意跟 SQL 反过来的
-
beego中limit的使用:qs.Limit(2,1).All(&user_arr)
-
sql的limit:limit 0,2; 从第0个数据开始,查询两条数据
Offset:设置 偏移行数,意思从什么位置开始查询
-
qs.Offset(20)
-
beego中使用:qs.Filter(“name__isnull”,false).Offset(1).All(&user_arr)
-
角标从0开始,代表第一条数据
GroupBy:分组
-
根据“By”指定的规则对数据进行分组
-
beego中使用GroupBy:qs.GroupBy(“age”).All(&user_arr)
-
sql:SELECT SUM(age) FROM `user` GROUP BY addr
-
group by 必须放在 order by 和 limit之前
OrderBy:排序
-
参数使用 expr
-
ASC升序,字段名前面没有- :qs.OrderBy(“age” ) 默认的
-
DESC降序,字段名前面有- :qs.OrderBy(“-age” )
-
根据多个字段排序,用逗号隔开: qs.OrderBy(“-age” ,“name”)
-
qs.OrderBy(“-age”).All(&user_arr)
Distinct:去重,没有参数
-
根据指定字段去重,需要在all方法中指定字段,否则根据所有字段去重
-
beego中的使用:qs.Distinct().All(&user_arr,“name”,“age”,“addr”)
-
sql:SELECT DISTINCT addr, age,name FROM `user`
Count:统计个数,没有参数,后面不能跟查询条数的方法
-
num, err := qs.Filter(“name__isnull”,false).Count()
-
统计的个数
-
错误信息
-
sql:SELECT COUNT(*) FROM `user`;
Exist:是否存在,没有参数,后面不能跟查询条数的方法
-
exict := qs.Filter(“name__isnull”,false).Exist()
-
返回true或false
Update:更新
-
依据当前查询条件,进行批量更新操作
-
num, err := o.QueryTable(“user”).Filter(“name”, “slene”).Update(orm.Params{“name”: “astaxie”,})
-
返回更新的条数和错误信息
Delete:删除
-
依据当前查询条件,进行批量删除操作
-
num, err := o.QueryTable(“user”).Filter(“name”, “slene”).Delete()
-
返回删除的条数和错误信息
**补充:不是QueryTable接口
insert:插入**
前提:
-
数据库已注册:orm.RegisterDataBase
-
模型已注册:orm.RegisterModel
5.5.1 在main.go中调用RunCommand命令
beego.Run()命令之前调用:
orm.RunCommand()
5.5.2 cmd中执行命令
go run main.go orm syncdb -h
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
r)
- sql的limit:limit 0,2; 从第0个数据开始,查询两条数据
Offset:设置 偏移行数,意思从什么位置开始查询
-
qs.Offset(20)
-
beego中使用:qs.Filter(“name__isnull”,false).Offset(1).All(&user_arr)
-
角标从0开始,代表第一条数据
GroupBy:分组
-
根据“By”指定的规则对数据进行分组
-
beego中使用GroupBy:qs.GroupBy(“age”).All(&user_arr)
-
sql:SELECT SUM(age) FROM `user` GROUP BY addr
-
group by 必须放在 order by 和 limit之前
OrderBy:排序
-
参数使用 expr
-
ASC升序,字段名前面没有- :qs.OrderBy(“age” ) 默认的
-
DESC降序,字段名前面有- :qs.OrderBy(“-age” )
-
根据多个字段排序,用逗号隔开: qs.OrderBy(“-age” ,“name”)
-
qs.OrderBy(“-age”).All(&user_arr)
Distinct:去重,没有参数
-
根据指定字段去重,需要在all方法中指定字段,否则根据所有字段去重
-
beego中的使用:qs.Distinct().All(&user_arr,“name”,“age”,“addr”)
-
sql:SELECT DISTINCT addr, age,name FROM `user`
Count:统计个数,没有参数,后面不能跟查询条数的方法
-
num, err := qs.Filter(“name__isnull”,false).Count()
-
统计的个数
-
错误信息
-
sql:SELECT COUNT(*) FROM `user`;
Exist:是否存在,没有参数,后面不能跟查询条数的方法
-
exict := qs.Filter(“name__isnull”,false).Exist()
-
返回true或false
Update:更新
-
依据当前查询条件,进行批量更新操作
-
num, err := o.QueryTable(“user”).Filter(“name”, “slene”).Update(orm.Params{“name”: “astaxie”,})
-
返回更新的条数和错误信息
Delete:删除
-
依据当前查询条件,进行批量删除操作
-
num, err := o.QueryTable(“user”).Filter(“name”, “slene”).Delete()
-
返回删除的条数和错误信息
**补充:不是QueryTable接口
insert:插入**
前提:
-
数据库已注册:orm.RegisterDataBase
-
模型已注册:orm.RegisterModel
5.5.1 在main.go中调用RunCommand命令
beego.Run()命令之前调用:
orm.RunCommand()
5.5.2 cmd中执行命令
go run main.go orm syncdb -h
[外链图片转存中…(img-16RUZhRJ-1715571918294)]
[外链图片转存中…(img-yZm1tYd4-1715571918295)]
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!