Beego脱坑(十四)ORM高级查询
title: Beego脱坑(十四)ORM高级查询
tags: go,beego,orm
author : Clown95
本文将讲述beego ORM的一些高级查询,这也是ORM最核心的部分,本文所有的操作都基于下面的student
表
Operators
在beego ORM中也有类似于SQL语句中的操作符,欲善其事,必利其器,我们先来了解他们,beego ORM目前支持的操作符为:
操作符 | 说明 | 等同Sql操作符 |
---|---|---|
gt | greater的缩写,表示大于的意思 | > |
gte | greater than or equal的缩写,即大于等于 | >= |
lt | less than的缩写,表示小于 | < |
lte | less thanor equal的缩写,小于等于 | <= |
in | 等同与sql语言中的in | in |
exact | 等于 | = |
contains | 包含,一般用于字符类型,如包含某某字符 | like '%查询内容%' |
startswith | 以…起始,一般用于字符类型,如从什么字符开始 | like '开始字符%' |
endswith | 以…结束 ,一般用于字符类型,如以什么字符结束 | like '%结束字符' |
isnull | 表示改字段不能为空 |
在beego中 操作符前面添加 字母 i
表示忽略大小写,如 iexact、icontains 、istartswith 和iendswith
exact
我们最先演示下exact 它相当于 = ,现在我们需要通过它查询出 stu_id =3 的一条数据。
func (this *OperatorsController) GetExact() {orm := orm.NewOrm()// 获取表句柄stu := Student{}qs := orm.QueryTable("student")// select * from student where id =3;err := qs.Filter("stu_id__exact", 3).One(&stu) // 过滤器if err != nil {this.Ctx.WriteString(strconv.Itoa(stu.StuId) + " " + stu.Name + " " + stu.Age + " " + stu.Hobby)}else{this.Ctx.WriteString("查询失败") }
}
上面的代码相当于sql语句 :
select * from student where id =3;
QueryTable("student")
: 返回student
表的QuerySeter 对象。ORM 以 QuerySeter 来组织查询,每个返回 QuerySeter 的方法都会获得一个新的 QuerySeter 对象;Filter("stu_id__exact" ,3)
: 用来过滤查询结果,起到包含条件
的作用,第一个参数是我匹配规则,第二个参数是我们匹配的值 ; 使用如果使用操作符,字段和操作符直接使用两个"_"连接,具体格式为:字段__操作符
;One(&stu)
: 返回单条记录 ,参数一般是结构体对象。
gte
现在我们来使用 gte
获取 age>=25岁的所有数据, 下面我们看代码。
func (this *OperatorsController) GetAllGte() {orm := orm.NewOrm()var stus = []*Student{}// 获取表句柄qs := orm.QueryTable("student")// select * from student where age>=25;n, err := qs.Filter("age__gte", 20).All(&stus) // 过滤器if err == nil && n > 0 {for i := 0; i < len(stus); i++ {this.Ctx.WriteString(strconv.Itoa(stus[i].StuId) + " " + stus[i].Name + " " + stus[i].Age + " " + stus[i].Hobby + "\n")}} else {this.Ctx.WriteString("查询失败")}
}
上面的代码相当于sql语句:
select * from student where age>=25;
All(&stus)
: 返回对应的结果集对象。 和One不一样的是,All返回所有符合条件的数据,参数是指针切片( []Type 或者[]*Type ),返回数据cols和error
in
现在我们通过 in 查询 stu_id 为 1、4、5、10的数据集。
func (this *OperatorsController) GetIn() {orm := orm.NewOrm()var stus = []*Student{}// 获取表句柄qs := orm.QueryTable("student")// select * from student where stu_id in(1,4,5,10);n, err := qs.Filter("stu_id__in",1,4,5,10 ).All(&stus) // 过滤器if err == nil && n > 0 {for i := 0; i < len(stus); i++ {this.Ctx.WriteString(strconv.Itoa(stus[i].StuId) + " " + stus[i].Name + " " + stus[i].Age + " " + stus[i].Hobby + "\n")}} else {this.Ctx.WriteString("查询失败")}
}
上面的代码相当于sql语句:
select * from student where stu_id in(1,4,5,10);
contains
接着我们使用 contains 来查询 name中包含 "小" 字的数据集。
func (this *OperatorsController) GetContains() {orm := orm.NewOrm()var stus = []*Student{}// 获取表句柄qs := orm.QueryTable("student")// select * from student where name like '小%';n, err := qs.Filter("name__contains", "小").All(&stus) // 过滤器if err == nil && n > 0 {for i := 0; i < len(stus); i++ {this.Ctx.WriteString(strconv.Itoa(stus[i].StuId) + " " + stus[i].Name + " " + stus[i].Age + " " + stus[i].Hobby + "\n")}} else {this.Ctx.WriteString("查询失败")}
}
上面的代码相当于sql语句:
select * from student where name like '小%';
操作符我们就演示到这里,其他的几个用法都大同小异,大家可以自己拓展。
高级查询接口
高级查询接口我们在 Operators 部分里面,使用过 Filter、One、All
这三个了。我们就不在重复介绍了,我们主要来了解下其他的接口函数。
方法 | 说明 |
---|---|
Exclude | 用来过滤查询结果,起到 排除条件的作用,相当于!Filter |
Limit | 限制最大返回数据行数 |
Offset | 设置偏移行数 |
GroupBy | 数据分组 |
OrderBy | 数据排序 |
Distinct | 获取不重复的数据 |
Count | 依据当前的查询条件,返回结果行数 |
Exist | 判断查询的数据是否存在 |
Values | 返回结果集数据,存储到map中 |
ValuesList | 顾名思义,返回的结果集以slice存储 |
PrepareInsert | 用于批量插入数据 |
Delete | 依据当前查询条件,进行批量删除操作 |
Update | 依据当前查询条件,进行批量更新操作 |
Exclude
现在我们来使用Exclude 排除 年龄小于等于25
的数据.
func (this * ADvancedApiController) GetExclude(){orm := orm.NewOrm()var stus = []*Student{}// 获取表句柄qs := orm.QueryTable("student")//select * from student where not age <=25 ;n, err := qs.Exclude("age__lte",25).All(&stus)if err == nil && n > 0 {for i := 0; i < len(stus); i++ {this.Ctx.WriteString(strconv.Itoa(stus[i].StuId) + " " + stus[i].Name + " " + stus[i].Age + " " + stus[i].Hobby + "\n")}} else {this.Ctx.WriteString("查询失败")}
}
上面的代码相当于sql语句:
select * from student where not age <=25 ;
Limit
有时候数据过多,我们只想显示部分数据,比如现在我们只需要显示前5个数据
func (this * ADvancedApiController) GetLimit(){orm := orm.NewOrm()var stus = []*Student{}// 获取表句柄qs := orm.QueryTable("student")//select * from student limit 5 ;n, err := qs.Limit(5) .All(&stus)if err == nil && n > 0 {for i := 0; i < len(stus); i++ {this.Ctx.WriteString(strconv.Itoa(stus[i].StuId) + " " + stus[i].Name + " " + stus[i].Age + " " + stus[i].Hobby + "\n")}} else {this.Ctx.WriteString("查询失败")}
}
上面的代码相当于sql语句:
select * from student limit 5 ;
当然我们还可以设置偏移量来设置分页 ,我们来修改Limit,显示6-10的数据:
n, err := qs.Limit(5,5) .All(&stus)
GroupBy
通过 age 进行分组
func (this * ADvancedApiController) GetGroupBy(){orm := orm.NewOrm()var stus = []*Student{}qs := orm.QueryTable("student")n, err := qs.GroupBy("age").All(&stus)if err == nil && n > 0 {for i := 0; i < len(stus); i++ {this.Ctx.WriteString(strconv.Itoa(stus[i].StuId) + " " + stus[i].Name + " " + stus[i].Age + " " + stus[i].Hobby + "\n")}} else {this.Ctx.WriteString("查询失败")}
}
OrderBy
通过 age 和 stu_id 进行排序 表达式前面使用 "-" 代表降序排序
func (this * ADvancedApiController) GetOrderBy(){orm := orm.NewOrm()var stus = []*Student{}qs := orm.QueryTable("student")n, err := qs.OrderBy("-age","stu_id").All(&stus)if err == nil && n > 0 {for i := 0; i < len(stus); i++ {this.Ctx.WriteString(strconv.Itoa(stus[i].StuId) + " " + stus[i].Name + " " + stus[i].Age + " " + stus[i].Hobby + "\n")}} else {this.Ctx.WriteString("查询失败")}
}
Count
使用Count 查询有多少行数据
func (this *ADvancedApiController) GetCount() {orm := orm.NewOrm()//select count(*) from student;n, err := orm.QueryTable("student").Count()if err != nil {this.Ctx.WriteString("查询出错!\n")return}else {this.Ctx.WriteString("n = " + strconv.Itoa(int(n)))}
}
上面的代码相当于sql语句:
select count(*) from student;
Exist
我们用 Exist 判断 stu_id =8 和 stu_id =15 的数据是否存在
func (this *ADvancedApiController) GetExist() {orm := orm.NewOrm()qs := orm.QueryTable("student")flag := qs.Filter("stu_id", 8).Exist()if flag {this.Ctx.WriteString("stu_id=8 存在\n")}else {this.Ctx.WriteString("stu_id=8 不存在\n")}flag = qs.Filter("stu_id", 15).Exist()if flag {this.Ctx.WriteString("stu_id=15 存在\n")}else {this.Ctx.WriteString("stu_id=15 不存在\n")}
}
Values
我们还可以 使用Values 返回结果集的 key => value 值 ,key 为Model里的Field name, value的值是interface{}类型,如果你要将value赋值给struct中的某字段,需要根据结构体对应字段类型使用断言获取真实值。
func (this *ADvancedApiController) GetValues() {//将每一条记录的字段作为键,数据作为值存入map中,每个map就是一条记录。var maps []orm.Params //[map, map, map]orm := orm.NewOrm()_, err := orm.QueryTable("student").Values(&maps, )if err != nil {this.Ctx.WriteString("查询出错!")return}for _, m := range maps {this.Ctx.WriteString(m["Name"].(string) + " " + m["Age"].(string) + " " + m["Hobby"].(string) + "\n")}
}
当然我们还可以直接指定 expr 级联返回需要的数据
func (this *ADvancedApiController) GetValuesField() {//将每一条记录的字段作为键,数据作为值存入map中,每个map就是一条记录。var maps []orm.Params //[map, map, map]orm := orm.NewOrm()_, err := orm.QueryTable("student").Values(&maps, "Name","Hobby")if err != nil {this.Ctx.WriteString("查询出错!")return}for _, m := range maps {this.Ctx.WriteString(m["Name"].(string) + " " + m["Hobby"].(string) + "\n")}
}
ValuesList
顾名思义,返回的结果集以slice存储,结果的排列与 Model 中定义的 Field 顺序一致,返回的每个元素值以 string 保存。
func (this *ADvancedApiController) GetValuesList() {var list []orm.ParamsListorm := orm.NewOrm()_, err := orm.QueryTable("student").ValuesList(&list, "Name", "Age", "Hobby")if err != nil {this.Ctx.WriteString("查询出错!")return}for _, row := range list {for _, col := range row {this.Ctx.WriteString(col.(string) + " ")}this.Ctx.WriteString("\n")}
}
PrepareInsert
我们使用PrepareInsert 在添加点数据,并且我们多提交一次数据,方便演示下面的批量删除
func (this *ADvancedApiController) GetPrepareInsert() {var stus []*Studentstu1 := Student{Name:"银之介", Age:"60", Hobby:"辣妹"}stu2 := Student{Name:"正男", Age:"5", Hobby:"小爱"}stu3 := Student{Name:"阿呆", Age:"6", Hobby:"甩鼻涕"}stu4 := Student{Name:"园长", Age:"56", Hobby:"园艺"}stus = append(stus, &stu1, &stu2, &stu3, &stu4)orm := orm.NewOrm()
// insert into student(name, age.hobby) values("银之介", "60", "辣妹"), (正男", "5", "小爱");insert, _ := orm.QueryTable("student").PrepareInsert()for _, stu := range stus {_, err := insert.Insert(stu)if err != nil {fmt.Println("插入错误!\n")continue}}insert.Close()this.Ctx.WriteString("插入结束!\n")
}
上面的代码相当于sql语句:
insert into student(name, age.hobby) values("银之介", "60", "辣妹"), ....,(园长", "56", "园艺");
Delete
还记得我们刚刚多提交了一次数据插入吗?我们原来的数据stu_id 最大为11, 所以我们删除 stu_id >11 的数据
func (this *ADvancedApiController) GetDelete() {orm := orm.NewOrm()qs:= orm.QueryTable("student")n,err:=qs.Filter("stu_id__gt",11).Delete()if err == nil&& n>0 {this.Ctx.WriteString("删除成功!\n")} else {this.Ctx.WriteString("删除失败!\n")}
}
Update
现在我们来批量更新下数据,下面我们需要把 stu_id=5 的 Hobby 改为 学习。
func (this *ADvancedApiController) GetUpdate() {orm1 := orm.NewOrm()qs:= orm1.QueryTable("student")n,err:=qs.Filter("stu_id",5).Update(orm.Params{"hobby": "学习",})if err == nil&& n>0 {this.Ctx.WriteString("修改成功!\n")} else {this.Ctx.WriteString("修改失败!\n")}
}
看到这里大家应该基本掌握接口的用法了,还有其他部分没演示的,请自行拓展我实在不想写了。
Beego脱坑(十四)ORM高级查询相关推荐
- 数据库系统原理与应用教程(070)—— MySQL 练习题:操作题 101-109(十四):查询条件练习
数据库系统原理与应用教程(070)-- MySQL 练习题:操作题 101-109(十四):查询条件练习 101.判断空值(1) 试卷答题记录表:exam_record(uid:用户ID,exam_i ...
- Beego脱坑(一)Beego简介和安装
title: Beego脱坑(一)Beego简介和安装 tags: go,beego author: Clown95 beego 简介 beego 是一个快速开发 Go 应用的 HTTP 框架,也是一 ...
- Oracle数据系列(四)、高级查询2
第四章.Oracle高级查询2 学习目标 4.1.模糊查询LIKE 查询时,字段内容并不一定与查询内容完全匹配,只要字段含有这些内容就行. #查询以李姓开头的员工信息 select * from em ...
- 微信小程序(第十四章) - 信息查询页面的实现
微信小程序(第十四章)- 信息查询页面的实现 前言 页面标题实现 信息框的实现 页面结构实现 页面样式实现 学生到校离校信息查询列表实现 页面结构实现 页面样式实现 正在加载实现 页面结构实现 页面样 ...
- 插入始终是1_C++入门篇(四十四),链表查询与结点插入
链表的查询 对链表进行各种操作时,需要先对某一个结点进行查询定位.假设数据中没有数据相同的结点,我们可以编写这样一个函数,查找到链表中符合条件的结点,我们在四十三篇的代码中声明搜索结点函数原型: 在底 ...
- [单刷 APUE 系列] 第十四章——高级 I/O
非阻塞I/O 在最前面,我们讲过IO分成带缓冲的IO和不带缓冲的IO,但是实际上,这个区别并不是很大,因为缓冲区并没有影响到实际的读写.我们知道,系统调用实际上分成两种,高速的系统调用和低速的系统调用 ...
- setitimer 创建两个定时器_JavaScript第二十四篇 高级定时器(下)
数组分块 所谓数组分块,就是当你发现某个循环占用了大量时间,同时对于上述两个问题,你的回答都是"否",那么你就可以使用定时器分割这个循环. 思路是结合定时器进行递归调用定时器 基本 ...
- Scala入门到精通——第二十四节 高级类型 (三)
本节主要内容 Type Specialization Manifest.TypeTag.ClassTag Scala类型系统总结 在Scala中,类(class)与类型(type)是两个不一样的概念. ...
- HyperLynx(十四)高级分析技术
1.BoardSim中的差分对 2.建立SPICE电路连接 1.BoardSim中的差分对 对差分引脚的分析是通过为其指定差分模型完成的.差分引脚在IBIS文件中有严格的定义,但是选定了差分模型后,用 ...
最新文章
- Android广播监听usb插拔状态
- 《虚拟化与云计算》第4章 虚拟化的业界动态
- fanuc机器人cm格式文件_了解发那科智能机器人自动化物流拆垛
- linux find命令使用示例
- 【华科考研机试题】最长最短文本
- java面试题二十五 构造函数
- Unable to load script from assets ‘index.android.bundle‘.
- php怎么实现匿名评论,PHP-匿名对象与匿名类的实现过程-0905
- lacp可以在access接口吗_【思唯网络学院】【干货】LACP与PAGP是什么?有何区别?...
- centos下的mysql安装
- github仓库主页介绍
- python2048游戏实训报告_Python 实现 2048 游戏
- 【2020总结】脚踏实地,仰望星空
- 利用百度地图根据三点求位置
- 【解决方案】宠物医院如何实现顾客医院联动的安全监控?EasyCVR视频图像智能分析远程监控方案介绍
- 自控力读书笔记 第四章 容忍罪恶: 为何善行之后会有恶行
- MySQL的触发器原理应用,after和before的区别
- 【分享】北京社保查询API
- 中国彩妆行业营销现状分析与投资机会研究报告2022版
- 致远SPM解决方案之资产管理
热门文章
- 支付宝当面付接入注意事项
- Kommander同步调试方法
- 如何拍出来好看的Vlog,必备小技能(三)?
- js向上向下取整_JS之向上取整、向下取整、四舍五入等
- javascript+css网址收藏
- access根据所属院系修改学号_用 Python 修改支付宝运动步数,轻松 TOP1
- 纳米数据体育数据供应商,体育赛事接口api,足球赛事比分api,服务商,数据接口调试,足球api接口演示示例
- Python 自定义对象数组 转JSON 字符串
- pythonsqrt取整函数_python取整函数
- 深度学习实战3-文本卷积神经网络(TextCNN)新闻文本分类