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高级查询相关推荐

  1. 数据库系统原理与应用教程(070)—— MySQL 练习题:操作题 101-109(十四):查询条件练习

    数据库系统原理与应用教程(070)-- MySQL 练习题:操作题 101-109(十四):查询条件练习 101.判断空值(1) 试卷答题记录表:exam_record(uid:用户ID,exam_i ...

  2. Beego脱坑(一)Beego简介和安装

    title: Beego脱坑(一)Beego简介和安装 tags: go,beego author: Clown95 beego 简介 beego 是一个快速开发 Go 应用的 HTTP 框架,也是一 ...

  3. Oracle数据系列(四)、高级查询2

    第四章.Oracle高级查询2 学习目标 4.1.模糊查询LIKE 查询时,字段内容并不一定与查询内容完全匹配,只要字段含有这些内容就行. #查询以李姓开头的员工信息 select * from em ...

  4. 微信小程序(第十四章) - 信息查询页面的实现

    微信小程序(第十四章)- 信息查询页面的实现 前言 页面标题实现 信息框的实现 页面结构实现 页面样式实现 学生到校离校信息查询列表实现 页面结构实现 页面样式实现 正在加载实现 页面结构实现 页面样 ...

  5. 插入始终是1_C++入门篇(四十四),链表查询与结点插入

    链表的查询 对链表进行各种操作时,需要先对某一个结点进行查询定位.假设数据中没有数据相同的结点,我们可以编写这样一个函数,查找到链表中符合条件的结点,我们在四十三篇的代码中声明搜索结点函数原型: 在底 ...

  6. [单刷 APUE 系列] 第十四章——高级 I/O

    非阻塞I/O 在最前面,我们讲过IO分成带缓冲的IO和不带缓冲的IO,但是实际上,这个区别并不是很大,因为缓冲区并没有影响到实际的读写.我们知道,系统调用实际上分成两种,高速的系统调用和低速的系统调用 ...

  7. setitimer 创建两个定时器_JavaScript第二十四篇 高级定时器(下)

    数组分块 所谓数组分块,就是当你发现某个循环占用了大量时间,同时对于上述两个问题,你的回答都是"否",那么你就可以使用定时器分割这个循环. 思路是结合定时器进行递归调用定时器 基本 ...

  8. Scala入门到精通——第二十四节 高级类型 (三)

    本节主要内容 Type Specialization Manifest.TypeTag.ClassTag Scala类型系统总结 在Scala中,类(class)与类型(type)是两个不一样的概念. ...

  9. HyperLynx(十四)高级分析技术

    1.BoardSim中的差分对 2.建立SPICE电路连接 1.BoardSim中的差分对 对差分引脚的分析是通过为其指定差分模型完成的.差分引脚在IBIS文件中有严格的定义,但是选定了差分模型后,用 ...

最新文章

  1. Android广播监听usb插拔状态
  2. 《虚拟化与云计算》第4章 虚拟化的业界动态
  3. fanuc机器人cm格式文件_了解发那科智能机器人自动化物流拆垛
  4. linux find命令使用示例
  5. 【华科考研机试题】最长最短文本
  6. java面试题二十五 构造函数
  7. Unable to load script from assets ‘index.android.bundle‘.
  8. php怎么实现匿名评论,PHP-匿名对象与匿名类的实现过程-0905
  9. lacp可以在access接口吗_【思唯网络学院】【干货】LACP与PAGP是什么?有何区别?...
  10. centos下的mysql安装
  11. github仓库主页介绍
  12. python2048游戏实训报告_Python 实现 2048 游戏
  13. 【2020总结】脚踏实地,仰望星空
  14. 利用百度地图根据三点求位置
  15. 【解决方案】宠物医院如何实现顾客医院联动的安全监控?EasyCVR视频图像智能分析远程监控方案介绍
  16. 自控力读书笔记 第四章 容忍罪恶: 为何善行之后会有恶行
  17. MySQL的触发器原理应用,after和before的区别
  18. 【分享】北京社保查询API
  19. 中国彩妆行业营销现状分析与投资机会研究报告2022版
  20. 致远SPM解决方案之资产管理

热门文章

  1. 支付宝当面付接入注意事项
  2. Kommander同步调试方法
  3. 如何拍出来好看的Vlog,必备小技能(三)?
  4. js向上向下取整_JS之向上取整、向下取整、四舍五入等
  5. javascript+css网址收藏
  6. access根据所属院系修改学号_用 Python 修改支付宝运动步数,轻松 TOP1
  7. 纳米数据体育数据供应商,体育赛事接口api,足球赛事比分api,服务商,数据接口调试,足球api接口演示示例
  8. Python 自定义对象数组 转JSON 字符串
  9. pythonsqrt取整函数_python取整函数
  10. 深度学习实战3-文本卷积神经网络(TextCNN)新闻文本分类