当前位置:首页 > 科技  > 软件

Find、Take、First和Last函数的区别

来源: 责编: 时间:2023-10-19 09:28:06 192观看
导读大家好,我是渔夫子。在gorm中,要想从数据库中查找数据有多种方法,可以通过Find、Take和First来查找。但它们之间又有一些不同。本文就详细介绍下他们之间的不同。一、准备工作首先我们有一个m_tests表,其中id字段是自增的

大家好,我是渔夫子。UOT28资讯网——每日最新资讯28at.com

在gorm中,要想从数据库中查找数据有多种方法,可以通过Find、Take和First来查找。但它们之间又有一些不同。本文就详细介绍下他们之间的不同。UOT28资讯网——每日最新资讯28at.com

一、准备工作

首先我们有一个m_tests表,其中id字段是自增的主键,同时该表里有3条数据。如下:UOT28资讯网——每日最新资讯28at.com

CREATE TABLE `m_tests` (  `id` bigint(20) NOT NULL AUTO_INCREMENT,  `name` varchar(100) NOT NULL DEFAULT '' COMMENT '姓名',  PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4;INSERT INTO test01.m_test (id,name) VALUES (1,'John'), (2,'Jack'),(3,'David');

基于这个表,我们来看看这几个函数查询出来的结果是什么。UOT28资讯网——每日最新资讯28at.com

二、First函数

我们通过ToSql函数将First函数转成对应的sql语句来看。如下:UOT28资讯网——每日最新资讯28at.com

func main() {	dsn := "username:password@tcp(127.0.0.1:3306)/test01?charset=utf8mb4&parseTime=True&loc=Local&timeout=1000ms"	config := &gorm.Config{		NamingStrategy: schema.NamingStrategy{			SingularTable: true, // 禁用表名复数		}}	db, _ := gorm.Open(mysql.Open(dsn), config)	var row MTest	sql := db.ToSQL(func(tx *gorm.DB) *gorm.DB {		return tx.First(&row)	})	fmt.Printf("接收的sql语句:%s/n", sql)}

通过该程序,可以看到最终的sql语句如下:UOT28资讯网——每日最新资讯28at.com

接收的sql语句:SELECT * FROM `m_test` ORDER BY `m_test`.`id` LIMIT 1

发现First函数是通过主键排序后,只获取一条数据。我们在通过explain来解释一下该条语句:UOT28资讯网——每日最新资讯28at.com

explain SELECT * FROM `m_test` ORDER BY `m_test`.`id` LIMIT 1

其输出结果如下:UOT28资讯网——每日最新资讯28at.com

也就是说在查询的时候也只扫描一行数据。也就是说First函数只扫描一行数据。UOT28资讯网——每日最新资讯28at.com

三、Last函数

同样,我们还是通过ToSQL来讲Last函数转化的sql语句打印出来:UOT28资讯网——每日最新资讯28at.com

func main() {	dsn := "username:password@tcp(127.0.0.1:3306)/test01?charset=utf8mb4&parseTime=True&loc=Local&timeout=1000ms"	config := &gorm.Config{		NamingStrategy: schema.NamingStrategy{			SingularTable: true, // 禁用表名复数		}}	db, _ := gorm.Open(mysql.Open(dsn), config)	var rows []MTest	sql := db.ToSQL(func(tx *gorm.DB) *gorm.DB {		return tx.Last(&rows)	})	fmt.Printf("接收的sql语句:%s/n", sql)  db.Last(&rows)  fmt.Printf("最终接收:%+v/n", rows)}

我们看到Last转换成的sql语句如下:UOT28资讯网——每日最新资讯28at.com

接收的sql语句:SELECT * FROM `m_test` ORDER BY `m_test`.`id` DESC LIMIT 1

所以,Take实际上是按主键倒序排列,并且只获取1行数据的一个sql。UOT28资讯网——每日最新资讯28at.com

我们再看最终获取的结果rows,虽然是个数组,但也只有一行数据。:UOT28资讯网——每日最新资讯28at.com

最终结果数据:[{Id:6 Name:}]

所以,Last和First的相同点在于只扫描到表的一条目标数据后就截止了,并赋值给接收变量。不同点在于First是按主键正序排列,Last是按主键倒序排列。UOT28资讯网——每日最新资讯28at.com

四、Take函数

再来看看Take函数的执行过程。如下:UOT28资讯网——每日最新资讯28at.com

func main() {	dsn := "username:password@tcp(127.0.0.1:3306)/test01?charset=utf8mb4&parseTime=True&loc=Local&timeout=1000ms"	config := &gorm.Config{		NamingStrategy: schema.NamingStrategy{			SingularTable: true, // 禁用表名复数		}}	db, _ := gorm.Open(mysql.Open(dsn), config)	var row MTest	sql := db.ToSQL(func(tx *gorm.DB) *gorm.DB {		return tx.Take(&row)	})	fmt.Printf("接收的sql语句:%s/n", sql)}

Take函数执行时最终转换成的sql语句如下:UOT28资讯网——每日最新资讯28at.com

SELECT * FROM `m_test` LIMIT 1

也是只获取一行数据,但和First不同的是缺少了Order BY m_test.id``。UOT28资讯网——每日最新资讯28at.com

我们再通过explain来解释下该条语句,如下, type列是ALL,rows列是3,因为我们表里只有3行数据。是全表扫描,然后再随机获取一行数据。如下:UOT28资讯网——每日最新资讯28at.com

mysql> explain SELECT * FROM `m_test` LIMIT 1;+----+-------------+--------+------------+------+---------------+------+---------+------+------+----------+-------+| id | select_type | table  | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra |+----+-------------+--------+------------+------+---------------+------+---------+------+------+----------+-------+|  1 | SIMPLE      | m_test | NULL       | ALL  | NULL          | NULL | NULL    | NULL |    3 |   100.00 | NULL  |+----+-------------+--------+------------+------+---------------+------+---------+------+------+----------+-------+1 row in set, 1 warning (0.09 sec)

所以,Take函数是扫描全表,并随机获取一条数据。所以,Take函数要比First函数性能差。UOT28资讯网——每日最新资讯28at.com

同时,我们注意到,因为在sql语句中可以看到都有LIMIT 1的限制,所以Take和First都只能获取一条数据,即便是给传递了一个数组,也只能获取一行数据,不能获取多行数据。UOT28资讯网——每日最新资讯28at.com

五、Find函数

再来看看Take函数的执行过程。我们首先给Find函数传递一个普通的非切片变量,如下:UOT28资讯网——每日最新资讯28at.com

func main() {	dsn := "username:password@tcp(127.0.0.1:3306)/test01?charset=utf8mb4&parseTime=True&loc=Local&timeout=1000ms"	config := &gorm.Config{		NamingStrategy: schema.NamingStrategy{			SingularTable: true, // 禁用表名复数		}}	db, _ := gorm.Open(mysql.Open(dsn), config)	var row MTest	sql := db.ToSQL(func(tx *gorm.DB) *gorm.DB {		return tx.Find(&row)	})	fmt.Printf("接收的sql语句:%s/n", sql)}

转换成的sql语句如下:UOT28资讯网——每日最新资讯28at.com

接收的sql语句:SELECT * FROM `m_test`

和First和Take相比,缺少了Order子句和Limit子句。扫描的是整个表,获取的也是表的所有数据,但因为接收者是一个非切片变量,所以最终只接收了一行数据到row中。UOT28资讯网——每日最新资讯28at.com

我们再来看看给Find传递一个切片变量来接收的情况:UOT28资讯网——每日最新资讯28at.com

func main() {	dsn := "username:password@tcp(127.0.0.1:3306)/test01?charset=utf8mb4&parseTime=True&loc=Local&timeout=1000ms"	config := &gorm.Config{		NamingStrategy: schema.NamingStrategy{			SingularTable: true, // 禁用表名复数		}}	db, _ := gorm.Open(mysql.Open(dsn), config)	var rows []MTest	tx.Find(&rows)	fmt.Printf("rows:%+v/n", rows)}

这个结果是接收所有查找到的行的数据到rows中。所以大家一定要注意,在使用Find查询的时候一定要加Where条件和查询的数量,以避免扫描和查询全表的数据,尤其是在大数量的表中。UOT28资讯网——每日最新资讯28at.com

六、总结

本文主要讲解了First、Last、Take和Find查询函数的不同之处。希望在使用过程中大家根据自己的应用场景选择合适的函数。UOT28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-14122-0.htmlFind、Take、First和Last函数的区别

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: 压测工具界的 “悍马” :wrk 使用

下一篇: Java中的代码重构:技巧、优秀实践与方法

标签:
  • 热门焦点
  • 《英雄联盟》夏季赛总决赛今日开打!JDG对阵LNG首发名单来了 Knight:准备三连冠

    《英雄联盟》夏季赛总决赛今日开打!JDG对阵LNG首发名单来了 Knight:准备三连冠

    8月5日消息,今日17:00,《英雄联盟》2023LPL夏季赛总决赛将正式开打,由JDG对阵LNG。对两支队伍来说,这场比赛不仅要争夺夏季赛冠军,更要决定谁才是LPL赛区一
  • Rust中的高吞吐量流处理

    Rust中的高吞吐量流处理

    作者 | Noz编译 | 王瑞平本篇文章主要介绍了Rust中流处理的概念、方法和优化。作者不仅介绍了流处理的基本概念以及Rust中常用的流处理库,还使用这些库实现了一个流处理程序
  • 得物效率前端微应用推进过程与思考

    得物效率前端微应用推进过程与思考

    一、背景效率工程随着业务的发展,组织规模的扩大,越来越多的企业开始意识到协作效率对于企业团队的重要性,甚至是决定其在某个行业竞争中突围的关键,是企业长久生存的根本。得物
  • 一个注解实现接口幂等,这样才优雅!

    一个注解实现接口幂等,这样才优雅!

    场景码猿慢病云管理系统中其实高并发的场景不是很多,没有必要每个接口都去考虑并发高的场景,比如添加住院患者的这个接口,具体的业务代码就不贴了,业务伪代码如下:图片上述代码有
  • Temu起诉SHEIN,跨境电商战事升级

    Temu起诉SHEIN,跨境电商战事升级

    来源 | 伯虎财经(bohuFN)作者 | 陈平安日前据外媒报道,拼多多旗下跨境电商平台Temu正对竞争对手SHEIN提起新诉讼,诉状称Shein“利用市场支配力量强迫服装厂商与之签订独家
  • 自律,给不了Keep自由!

    自律,给不了Keep自由!

    来源 | 互联网品牌官作者 | 李大为编排 | 又耳 审核 | 谷晓辉自律能不能给用户自由暂时不好说,但大概率不能给Keep自由。近日,全球最大的在线健身平台Keep正式登陆港交所,努力
  • 东方甄选单飞:有些鸟注定是关不住的

    东方甄选单飞:有些鸟注定是关不住的

    作者:彭宽鸿来源:华尔街科技眼‍‍‍‍‍‍‍‍‍‍东方甄选创始人俞敏洪带队的“7天甘肃行”直播活动已在近日顺利收官。成立后一
  • 华为开发者大会2023日程公开:开设鸿蒙HarmonyOS 4体验区

    华为开发者大会2023日程公开:开设鸿蒙HarmonyOS 4体验区

    IT之家 7 月 31 日消息,华为今日公布了 HDC.Together 开发者大会 2023 的详细日程。整场大会将于 8 月 4 日-6 日之间举行,届时将发布最新一代鸿蒙 H
  • 亲历马斯克血洗Twitter,硅谷的苦日子在后头

    亲历马斯克血洗Twitter,硅谷的苦日子在后头

    文/刘哲铭  编辑/李薇  马斯克再次挥下裁员大刀。  美国时间11月14日,Twitter约4400名外包员工遭解雇,此次被解雇的员工的主要工作为内容审核等。此前,T
Top