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 接口和其部分方法的使用。限于篇幅,没有介绍关联查询和构造查询,关于未提及的内容,读者朋友可以参考官方手册。





目录
相关文章
|
15天前
|
Java API 数据库
构建RESTful API已经成为现代Web开发的标准做法之一。Spring Boot框架因其简洁的配置、快速的启动特性及丰富的功能集而备受开发者青睐。
【10月更文挑战第11天】本文介绍如何使用Spring Boot构建在线图书管理系统的RESTful API。通过创建Spring Boot项目,定义`Book`实体类、`BookRepository`接口和`BookService`服务类,最后实现`BookController`控制器来处理HTTP请求,展示了从基础环境搭建到API测试的完整过程。
31 4
|
17天前
|
XML JSON API
ServiceStack:不仅仅是一个高性能Web API和微服务框架,更是一站式解决方案——深入解析其多协议支持及简便开发流程,带您体验前所未有的.NET开发效率革命
【10月更文挑战第9天】ServiceStack 是一个高性能的 Web API 和微服务框架,支持 JSON、XML、CSV 等多种数据格式。它简化了 .NET 应用的开发流程,提供了直观的 RESTful 服务构建方式。ServiceStack 支持高并发请求和复杂业务逻辑,安装简单,通过 NuGet 包管理器即可快速集成。示例代码展示了如何创建一个返回当前日期的简单服务,包括定义请求和响应 DTO、实现服务逻辑、配置路由和宿主。ServiceStack 还支持 WebSocket、SignalR 等实时通信协议,具备自动验证、自动过滤器等丰富功能,适合快速搭建高性能、可扩展的服务端应用。
75 3
|
22天前
|
设计模式 JavaScript 前端开发
浅谈JavaScript 框架在现代 Web 开发中的作用
浅谈JavaScript 框架在现代 Web 开发中的作用
31 12
|
16天前
|
前端开发 JavaScript UED
构建现代Web应用:使用React框架打造单页面应用
【10月更文挑战第9天】构建现代Web应用:使用React框架打造单页面应用
|
16天前
|
前端开发 JavaScript 开发者
探索现代Web前端技术:React框架入门
【10月更文挑战第9天】 探索现代Web前端技术:React框架入门
|
22天前
|
存储 SQL 数据库
使用Python和Flask框架创建Web应用
【10月更文挑战第3天】使用Python和Flask框架创建Web应用
21 1
|
23天前
|
前端开发 Java API
JAVA Web 服务及底层框架原理
【10月更文挑战第1天】Java Web 服务是基于 Java 编程语言用于开发分布式网络应用程序的一种技术。它通常运行在 Web 服务器上,并通过 HTTP 协议与客户端进行通信。
15 1
|
23天前
|
开发框架 前端开发 数据库
使用Django框架构建一个完整的Web应用
【10月更文挑战第2天】使用Django框架构建一个完整的Web应用
28 1
|
15天前
|
前端开发 中间件 Go
实践Golang语言N层应用架构
【10月更文挑战第2天】本文介绍了如何在Go语言中使用Gin框架实现N层体系结构,借鉴了J2EE平台的多层分布式应用程序模型。文章首先概述了N层体系结构的基本概念,接着详细列出了Go语言中对应的构件名称,包括前端框架(如Vue.js、React)、Gin的处理函数和中间件、依赖注入和配置管理、会话管理和ORM库(如gorm或ent)。最后,提供了具体的代码示例,展示了如何实现HTTP请求处理、会话管理和数据库操作。
23 0
|
19天前
|
NoSQL Java 数据库连接
springBoot:整合其他框架&condition&切换web配置 (五)
本文档介绍了如何在Spring Boot项目中整合JUnit、Redis和MyBatis等框架,并提供了相应的依赖配置示例。同时,还展示了如何通过条件注解实现Bean的条件创建,以及如何切换Web服务器配置,从默认的Tomcat切换到Jetty。