gorm是一款优秀的国产golang orm关系型数据库框架,在国内外使用比较广泛。它的链式调用还算是一种符合人类思维的风格。

不过在使用过程中也遇到一些困扰,比如:Model, Find, First, Where这些函数该什么时候使用,有时候会有边界不清楚,使用混乱的情况。

以下代码示例使用v2版本,v1和v2大体上相同,有些细微的不同

Where和Find


search := User{UserName:"月盾"}db.Find(&user, search)// SELECT * FROM `user` WHERE `user`.`user_name` = '月盾'db.Where(search).Find(&user)// SELECT * FROM `user` WHERE `user`.`user_name` = '月盾'

以上两种查询方式结果一样。

Find(dest interface{}, conds ...interface{})Find函数有两个参数,dest是数据接收者,conds是查询条件。所以Find也是可以代替Where来传入条件的。

Where的参数主要分为两类:String,Struct&Map。还有其他不常用类型。

String参数

当使用string参数时,使用方式类似于fmt.Printf,第一个参数为字符串格式,使用?作为占位符,后面的参数作为值。

Struct&Map参数

使用结构体和映射作为参数时,则推荐一个参数即可,struct和map本身就是键值对格式。否则容易引起混淆。比如这样的:


db.Where(&User{Name: "jinzhu"}, "name", "Age").Find(&users)// SELECT * FROM users WHERE name = "jinzhu" AND age = 0;db.Where(&User{Name: "jinzhu"}, "Age").Find(&users)// SELECT * FROM users WHERE age = 0;

注意 当使用结构作为条件查询时,GORM 只会查询非零值字段。这意味着如果您的字段值为 0、’’、false 或其他 零值,该字段不会被用于构建查询条件,例如:


db.Where(&User{Name: "jinzhu", Age: 0}).Find(&users)// SELECT * FROM users WHERE name = "jinzhu";

你可以使用 map 来构建查询条件,它会使用所有的值,例如:


db.Where(map[string]interface{}{"Name": "jinzhu", "Age": 0}).Find(&users)// SELECT * FROM users WHERE name = "jinzhu" AND age = 0;

Find和First


db.Find(&user)// SELECT * FROM `user`db.First(&user)// SELECT * FROM `user` ORDER BY `user`.`id` LIMIT 1

Find查询结果是列表,First查询的是单条数据。

First(dest interface{}, conds ...interface{})First参数和Find一样,同样可以传递条件参数。

Find和Scan


db.Raw("select * from user where id=?", 1).Find(&user)db.Raw("select * from user where id=?", 1).Scan(&user)

在使用Raw自定义SQL查询时,使用Scan来接收数据,虽然Find也是可以接收的,但是Find主要还是用来带条件查询的,链接到Raw后面时条件是不起作用的。所以用Scan函数单纯的接收数据就行了。

Model()函数什么时候用?

对于查询来说,一般使用Find,First就够了。当查询链中没有用到Find,First等函数时,这时就无法指定要查询的表了,此时就要用Model来指定表。

另外的场景就是更新操作中使用。

Update(column string, value interface{})

更新函数的参数是(字段,值),没有能够确定表的参数,所以更新操作需要用到Model。

举例:

db.Model(&User{ID: 1}).Updates(User{Mobile: "13333333333"})

此时使用Model不仅可以指定表,还可以指定查询条件,但是这个条件却只能是id,不能使用其他条件。

像这样是不行的:

db.Model(&User{UserName: "月盾"}).Updates(User{Mobile: "13333333333"})

所以要使用其他条件就要用到Where函数了。

函数顺序

官网文档的示例中展示的例子都是这种格式:


db.Where("user_name = ?", "月盾").Find(&users)// SELECT * FROM users WHERE user_name = '月盾';

你可能会想,Where和Find函数的顺序可以调换吗?答案是:不能!

对于Find函数,他的单词意义是:查找。很容易让人理解成SQL中的select,这确实是一个误导,实际上应该理解成todestination,可以解释为:将前面的查询结果输出到某个地方。

至于其他函数则可以调换位置,如:


db.Where("user_name = ?", "月盾").Order("id desc").Find(&user)db.Order("id desc").Where("user_name = ?", "月盾").Find(&user)// SELECT * FROM `user` WHERE user_name = '月盾' ORDER BY id desc

Where和Order的顺序则不影响最终输出SQL。

gorm目前有两个大版本:v1和v2,它们的差异可以查看官网文档[

GORM 2.0 发布说明

](https://gorm.io/zh_CN/docs/v2_release_note.html)

原文:https://www.yuedun.wang/2021/07/gorm-model-find-first/

Gorm Model FindFirstWhere等查询函数的区别相关推荐

  1. 05-【gorm】GORM Model FindFirstWhere等查询函数的区别

    Gorm Model FindFirstWhere等查询函数的区别_月盾的专栏-CSDN博客

  2. 实测MySQL 查询结果保留两位小数函数的区别汇总

    MySQL查询结果保留两位小数常用的几个函数的区别,使用场景. 1.随机函数format(x,d) 2.格式化小数函数format(x,d) 例如: select format(23456.789,2 ...

  3. render函数和redirect函数的区别+反向解析

    render函数和redirect函数的区别+反向解析 1.视图函数:一定是要包含两个对象的(render源码里面有HttpResponse对象)   request对象:----->所有的请求 ...

  4. 【Pytorch】model.train()和model.eval()用法和区别,以及model.eval()和torch.no_grad()的区别

    model.train() 启用 Batch Normalization 和 Dropout 如果模型中有BN层(Batch Normalization)和Dropout,需要在训练时添加model. ...

  5. 存储过程和函数的区别?

    存储过程和函数的区别? 1)一般来说,存储过程实现的功能要复杂一点,而函数的实现的功能针对性比较强.存储过程,功能强大,可以执行包括修改表等一系列数据库操作:用户定义函数不能用于执行一组修改全局数据库 ...

  6. mysql的空间查询函数_MYSQL空间查询函数

    数据写入 插入时使用ST_GeomFromText,也可使用GeomFromText INSERT INTOt_customers ( lon_lat_point )VALUES( GeomFromT ...

  7. mysql 空间查询_MYSQL空间查询函数

    数据写入 插入时使用ST_GeomFromText,也可使用GeomFromText INSERT INTOt_customers ( lon_lat_point )VALUES( GeomFromT ...

  8. Django学习笔记(3):使用模型类进行查询(查询函数、F对象、Q对象、聚合函数、查询集、模型类关系、关联查询、自关联、管理器)

    文章目录 1.查询函数 2.F对象 3.Q对象 4.聚合函数 5.Count函数 6.查询集 查询集的特性 对查询集进行切片 判断一个查询集中是否有数据 7.模型类之间的关系 一对多关系 多对多关系 ...

  9. Arduino中Serial.print()与Serial.write()函数的区别,以及串口通信中十六进制与字符串的收发格式问题和转换过程详解

    1.串口通信中十六进制和字符数据的区别 串口收发数据时字符.十六进制.二进制格式详细区分 ASCII码查询表格 在使用串口发送数据时可以选择字符串(ASCII)发送或者十六进制(Hex)发送,通常情况 ...

  10. sum()函数和count()函数的区别

    sum()函数和count()函数的区别: 1)求和用累加sum(),求行的个数用累计count() 2)数据库中对空值的处理:sum()不计算,count()认为没有此项: 示例: SUM是对符合条 ...

最新文章

  1. angular react_Angular 2 vs React:将会有鲜血
  2. 实战:基于OpenCV的人眼检测
  3. 5.2基于JWT的令牌生成和定制「深入浅出ASP.NET Core系列」
  4. 学习python的一些心得和经验
  5. 好渴望 wacom Intuos3
  6. java随机数语句_Java语言程序设计(七)Math类生成随机数及if语句
  7. maven将xml文件一起打包
  8. Spring的静态代理和动态代理
  9. python入门--基本语法
  10. vi或vim查找替换
  11. oracle 字段以逗号结尾的更新 数据库_Oracle数据库某个字段的值为逗号分隔的多个值组成的字符串,以一个多选的下拉框进行查询...
  12. golang中的匿名组合
  13. Chrome在302重定向的时候对原请求产生2次请求的问题说明
  14. 国内成品油价近期历次调整一览
  15. 弹出页面,弹出框,$(‘‘).modal({});模态框
  16. Linux电源驱动-Linux Cpuidle Framework
  17. win10设置无盘服务器,win10系统无盘安装系统的操作方法
  18. 2021-02-01 25 个常用 Matplotlib 图的 Python 代码
  19. 教育技术学就业方向_教育技术学专业就业方向与就业前景
  20. git各种异常问题整理

热门文章

  1. mysql重复查询最后一条数据_sql查询表里重复记录现取重复最后一条记录方法
  2. CSS3 之 童年的纸飞机
  3. 同名的同义词和视图解惑
  4. 面试之springboot是什么?
  5. Bypass disable_function
  6. 虚拟空间 搬迁 云服务器,服务器空间搬迁到虚拟主机
  7. Grammarly:最优秀的日常英文写作辅助工具——论文英文校验
  8. 关于一个博客系统的 整体架构与技术
  9. java自己写母版_Java 创建并用应用幻灯片母版
  10. 美团O2O供应链系统架构设计解析