Golang 语言 Web 框架 beego v2 之读操作(下)

简介: Golang 语言 Web 框架 beego v2 之读操作(下)

04

条件查询


上一小节介绍的查询方式,都没有使用查询条件,本小节内容介绍条件查询,在介绍条件查询之前,先来介绍一下 expr,expr 是 QuerySeter 用于描述字段和描述sql 操作符的一种表达方式。


字段组合的前后顺序依照表的关系,比如 User 表拥有 Profile 的外键,那么对 User 表查询对应的 Profile.Age 为条件,则使用 Profile__Age。


注意,字段的分隔符号使用双下划线 __,除了描述字段, expr 的尾部可以增加操作符以执行对应的 sql 操作。比如 Profile__Age__gt 代表 Profile.Age > 18 的条件查询。


expr 示例代码:


qs.Filter("id", 1) // WHERE id = 1
qs.Filter("profile__age", 18) // WHERE profile.age = 18
qs.Filter("Profile__Age", 18) // 使用字段名和 Field 名都是允许的
qs.Filter("profile__age__gt", 18) // WHERE profile.age > 18
qs.Filter("profile__age__gte", 18) // WHERE profile.age >= 18
qs.Filter("profile__age__in", 18, 20) // WHERE profile.age IN (18, 20)
qs.Filter("profile__age__in", 18, 20).Exclude("profile__lt", 1000)
// WHERE profile.age IN (18, 20) AND NOT profile_id < 1000

注释后面将描述对应的 sql 语句,仅仅是描述 expr 的类似结果,并不代表实际生成的语句。


表达式和操作符

在介绍 QuerySeter 的方法之前,先介绍表达式和操作符,表达式和操作符适用于 QuerySeter 的所有方法。


表达式

  • 等于
  • 大于 gt
  • 大于等于 gte
  • 小于 lt
  • 小于等于 lte
  • IN
  • isnull (true:isnull / false:is not null)


操作符

  • exact 等于(区分字母大小写)

iexact 等于(不区分大小写)

contains Like(区分大小写)

icontains Like( 不区分大小写)

startswith (前置模糊查询,区分大小写)

istartswith(前置模糊查询,不区分大小写)

endswith(后置模糊查询,区分大小写)

iendswith(后置模糊查询,不区分大小写)


QuerySeter 的方法

Filter 包含

Filter 方法用来过滤查询结果,起到「包含条件」的作用。


Exclude 排除

Exclude 方法用来过滤查询结果,起到「排除条件」的作用。


Limit 限制条数

Limit 方法限制最大返回的记录数,默认值为 1000。第二个参数可以设置 offset,需要特别注意的是,这里的 limit / offset 和原生 sql 中的 limit / offset 是反过来的。


Offset 偏移

Offset 方法用来设置偏移量。


OrderBy 排序 "column" means ASC, "-column" means DESC.

OrderBy 方法用于排序,参数使用 expr 表达方式,默认是 ASC 排序规则,在 expr 前面用减号「-」表示 DESC 排序规则。


Distinct 方法

Distinct 方法返回指定字段不重复的查询结果。


Exist 是否存在

Exist 方法用于判断符合查询条件的结果是否存在。


示例代码:


func (u *UserController) Read() {
  o := orm.NewOrm()
  // 条件查询
  var users []models.User
  // Filter 包含
  // 表达式和操作符
  // 等于
  err := o.QueryTable(new(models.User)).Filter("id", 2).One(&users)
  // 大于
  // num, err := o.QueryTable(new(models.User)).Filter("id__gt", 9).All(&users)
  // 大于等于
  // num, err := o.QueryTable(new(models.User)).Filter("id__gte", 9).All(&users)
  // 小于
  // num, err := o.QueryTable(new(models.User)).Filter("id__lt", 5).All(&users)
  // 小于等于
  // num, err := o.QueryTable(new(models.User)).Filter("id__lte", 5).All(&users)
  // IN
  // num, err := o.QueryTable(new(models.User)).Filter("id__in", 2, 4).All(&users)
  // isnull (true:isnull / false: is not null)
  // num, err := o.QueryTable(new(models.User)).Filter("id__isnull", false).All(&users)
  // num, err := o.QueryTable(new(models.User)).Filter("id__isnull", true).All(&users)
  // exact 等于(区分字母大小写)
  // num, err := o.QueryTable(new(models.User)).Filter("name__exact", "frank").All(&users)
  // iexact 等于(不区分大小写)
  // num, err := o.QueryTable(new(models.User)).Filter("name__iexact", "frank").All(&users)
  // contains Like(区分大小写)
  // num, err := o.QueryTable(new(models.User)).Filter("name__contains", "frank").All(&users)
  // icontains Like( 不区分大小写)
  // num, err := o.QueryTable(new(models.User)).Filter("name__icontains", "frank").All(&users)
  // startswith (前置模糊查询,区分大小写)
  // num, err := o.QueryTable(new(models.User)).Filter("name__startswith", "fran").All(&users)
  // istartswith(前置模糊查询,不区分大小写)
  // num, err := o.QueryTable(new(models.User)).Filter("name__istartswith", "fran").All(&users)
  // endswith(后置模糊查询,区分大小写)
  // num, err := o.QueryTable(new(models.User)).Filter("name__endswith", "er").All(&users)
  // iendswith(后置模糊查询,不区分大小写)
  // num, err := o.QueryTable(new(models.User)).Filter("name__iendswith", "er").All(&users)
  // Exclude 排除
  // num, err := o.QueryTable(new(models.User)).Exclude("name__exact", "frank").All(&users)
  // Limit 限制条数
  // num, err := o.QueryTable(new(models.User)).Limit(4).All(&users)
  // Offset 偏移
  // num, err := o.QueryTable(new(models.User)).Offset(4).All(&users)
  // OrderBy 排序 "column" means ASC, "-column" means DESC.
  // num, err := o.QueryTable(new(models.User)).OrderBy("id").All(&users)
  // num, err := o.QueryTable(new(models.User)).OrderBy("-id").All(&users)
  // Distinct 去重
  // num, err := o.QueryTable(new(models.User)).Filter("id__gt", 9).Distinct().All(&users, "Age")
  // Exist 是否存在
  // isExisted := o.QueryTable(new(models.User)).Filter("name__exact", "frank1").Exist()
  // fmt.Println("isExisted:", isExisted)
  if err != nil {
    log.Fatalln(err.Error())
    return
  }
  fmt.Printf("user:%+v\n", users)
}


05

原生 SQL 查询


beego ORM 原生 SQL 查询,通过获取一个 RawSeter 对象,使用 RawSeter 对象的 Raw 方法,实现原生 SQL 查询。


Raw 方法,参数 1 是原生 sql 语句的字符串,参数 2 是原生 sql 语句的参数,该参数支持模型结构体,切片和数组。


RawSeter 接口的方法:


type RawSeter interface {
    Exec() (sql.Result, error)
    QueryRow(containers ...interface{}) error
    QueryRows(containers ...interface{}) (int64, error)
    SetArgs(...interface{}) RawSeter
    Values(container *[]Params, cols ...string) (int64, error)
    ValuesList(container *[]ParamsList, cols ...string) (int64, error)
    ValuesFlat(container *ParamsList, cols ...string) (int64, error)
    RowsToMap(result *Params, keyCol string, valueCol string) (int64, error)
    RowsToStruct(ptrStruct interface{}, keyCol string, valueCol string) (int64, error)
    Prepare() (RawPreparer, error)
}


接下来,我们来介绍一下 QueryRow 方法和 QueryRows 方法。


QueryRow 方法

QueryRow 方法返回单条查询数据,不定长参数接收指针类型。


示例代码:


func (u *UserController) Read() {
  o := orm.NewOrm()
    var user models.User
  err := o.Raw("SELECT id,name,age FROM beego_user WHERE id = ?", 2).QueryRow(&user)
  if err != nil {
    log.Fatalln(err.Error())
    return
  }
  fmt.Printf("user:%+v\n", user)
}


QueryRows 方法

QueryRows 方法返回多条查询数据,不定长参数接收指针类型。返回结果是查询结果集的数量和错误。


示例代码:


func (u *UserController) Read() {
  o := orm.NewOrm()
  var users []models.User
  ids := []int{1,3,5}
  num, err := o.Raw("SELECT id,name,age FROM beego_user WHERE id IN (?,?,?)", ids).QueryRows(&users)
  if err != nil {
    log.Fatalln(err.Error())
    return
  }
  fmt.Printf("nums:%d user:%+v\n", num, users)
}


06

总结


本文主要介绍 beego ORM 的读操作,包含普通查询、高级查询和原生 SQL 查询,先是介绍了普通查询,然后是介绍高级查询,包含 expr 表达式,QuerySeter 接口和其部分方法的使用,最后介绍了 RawSeter 接口和其部分方法的使用。限于篇幅,没有介绍关联查询和构造查询,关于未提及的内容,读者朋友可以参考官方手册。





目录
相关文章
|
1月前
|
Java API 数据库
构建RESTful API已经成为现代Web开发的标准做法之一。Spring Boot框架因其简洁的配置、快速的启动特性及丰富的功能集而备受开发者青睐。
【10月更文挑战第11天】本文介绍如何使用Spring Boot构建在线图书管理系统的RESTful API。通过创建Spring Boot项目,定义`Book`实体类、`BookRepository`接口和`BookService`服务类,最后实现`BookController`控制器来处理HTTP请求,展示了从基础环境搭建到API测试的完整过程。
42 4
|
1月前
|
XML JSON API
ServiceStack:不仅仅是一个高性能Web API和微服务框架,更是一站式解决方案——深入解析其多协议支持及简便开发流程,带您体验前所未有的.NET开发效率革命
【10月更文挑战第9天】ServiceStack 是一个高性能的 Web API 和微服务框架,支持 JSON、XML、CSV 等多种数据格式。它简化了 .NET 应用的开发流程,提供了直观的 RESTful 服务构建方式。ServiceStack 支持高并发请求和复杂业务逻辑,安装简单,通过 NuGet 包管理器即可快速集成。示例代码展示了如何创建一个返回当前日期的简单服务,包括定义请求和响应 DTO、实现服务逻辑、配置路由和宿主。ServiceStack 还支持 WebSocket、SignalR 等实时通信协议,具备自动验证、自动过滤器等丰富功能,适合快速搭建高性能、可扩展的服务端应用。
101 3
|
17天前
|
设计模式 前端开发 数据库
Python Web开发:Django框架下的全栈开发实战
【10月更文挑战第27天】本文介绍了Django框架在Python Web开发中的应用,涵盖了Django与Flask等框架的比较、项目结构、模型、视图、模板和URL配置等内容,并展示了实际代码示例,帮助读者快速掌握Django全栈开发的核心技术。
104 45
|
13天前
|
SQL 安全 PHP
探索PHP的现代演进:从Web开发到框架创新
PHP是一种流行的服务器端脚本语言,自诞生以来在Web开发领域占据重要地位。从简单的网页脚本到支持面向对象编程的现代语言,PHP经历了多次重大更新。本文探讨PHP的现代演进历程,重点介绍其在Web开发中的应用及框架创新,如Laravel、Symfony等。这些框架不仅简化了开发流程,还提高了开发效率和安全性。
22 3
|
12天前
|
前端开发 JavaScript 开发工具
从框架到现代Web开发实践
从框架到现代Web开发实践
23 1
|
15天前
|
SQL 安全 PHP
探索PHP的现代演进:从Web开发到框架创新
PHP 自发布以来一直在 Web 开发领域占据重要地位,历经多次重大更新,从简单的脚本语言进化为支持面向对象编程的现代语言。本文探讨 PHP 的演进历程,重点介绍其在 Web 开发中的应用及框架创新。自 PHP 5.3 引入命名空间后,PHP 迈向了面向对象编程时代;PHP 7 通过优化内核大幅提升性能;PHP 8 更是带来了属性、刚性类型等新特性。
24 3
|
18天前
|
前端开发 JavaScript
Bootstrap Web 前端 UI 框架
Bootstrap 是快速开发 Web 应用程序的前端工具包。
30 3
|
18天前
|
安全 数据库 开发者
Python Web开发:Django框架下的全栈开发实战
【10月更文挑战第26天】本文详细介绍了如何在Django框架下进行全栈开发,包括环境安装与配置、创建项目和应用、定义模型类、运行数据库迁移、创建视图和URL映射、编写模板以及启动开发服务器等步骤,并通过示例代码展示了具体实现过程。
31 2
|
1月前
|
前端开发 JavaScript UED
构建现代Web应用:使用React框架打造单页面应用
【10月更文挑战第9天】构建现代Web应用:使用React框架打造单页面应用
|
1月前
|
前端开发 JavaScript 开发者
探索现代Web前端技术:React框架入门
【10月更文挑战第9天】 探索现代Web前端技术:React框架入门