成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Find、Take、First和Last函數(shù)的區(qū)別

開發(fā) 前端
本文主要講解了First、Last、Take和Find查詢函數(shù)的不同之處。希望在使用過程中大家根據(jù)自己的應(yīng)用場景選擇合適的函數(shù)。

大家好,我是漁夫子。

在gorm中,要想從數(shù)據(jù)庫中查找數(shù)據(jù)有多種方法,可以通過Find、Take和First來查找。但它們之間又有一些不同。本文就詳細(xì)介紹下他們之間的不同。

一、準(zhǔn)備工作

首先我們有一個m_tests表,其中id字段是自增的主鍵,同時該表里有3條數(shù)據(jù)。如下:

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');

基于這個表,我們來看看這幾個函數(shù)查詢出來的結(jié)果是什么。

二、First函數(shù)

我們通過ToSql函數(shù)將First函數(shù)轉(zhuǎn)成對應(yīng)的sql語句來看。如下:

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, // 禁用表名復(fù)數(shù)
		}}
	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語句如下:

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

發(fā)現(xiàn)First函數(shù)是通過主鍵排序后,只獲取一條數(shù)據(jù)。我們在通過explain來解釋一下該條語句:

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

其輸出結(jié)果如下:

也就是說在查詢的時候也只掃描一行數(shù)據(jù)。也就是說First函數(shù)只掃描一行數(shù)據(jù)。

三、Last函數(shù)

同樣,我們還是通過ToSQL來講Last函數(shù)轉(zhuǎn)化的sql語句打印出來:

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, // 禁用表名復(fù)數(shù)
		}}
	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轉(zhuǎn)換成的sql語句如下:

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

所以,Take實(shí)際上是按主鍵倒序排列,并且只獲取1行數(shù)據(jù)的一個sql。

我們再看最終獲取的結(jié)果rows,雖然是個數(shù)組,但也只有一行數(shù)據(jù)。:

最終結(jié)果數(shù)據(jù):[{Id:6 Name:}]

所以,Last和First的相同點(diǎn)在于只掃描到表的一條目標(biāo)數(shù)據(jù)后就截止了,并賦值給接收變量。不同點(diǎn)在于First是按主鍵正序排列,Last是按主鍵倒序排列。

四、Take函數(shù)

再來看看Take函數(shù)的執(zhí)行過程。如下:

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, // 禁用表名復(fù)數(shù)
		}}
	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函數(shù)執(zhí)行時最終轉(zhuǎn)換成的sql語句如下:

SELECT * FROM `m_test` LIMIT 1

也是只獲取一行數(shù)據(jù),但和First不同的是缺少了Order BY m_test.id``。

我們再通過explain來解釋下該條語句,如下, type列是ALL,rows列是3,因?yàn)槲覀儽砝镏挥?行數(shù)據(jù)。是全表掃描,然后再隨機(jī)獲取一行數(shù)據(jù)。如下:

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函數(shù)是掃描全表,并隨機(jī)獲取一條數(shù)據(jù)。所以,Take函數(shù)要比First函數(shù)性能差。

同時,我們注意到,因?yàn)樵趕ql語句中可以看到都有LIMIT 1的限制,所以Take和First都只能獲取一條數(shù)據(jù),即便是給傳遞了一個數(shù)組,也只能獲取一行數(shù)據(jù),不能獲取多行數(shù)據(jù)。

五、Find函數(shù)

再來看看Take函數(shù)的執(zhí)行過程。我們首先給Find函數(shù)傳遞一個普通的非切片變量,如下:

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, // 禁用表名復(fù)數(shù)
		}}
	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)
}

轉(zhuǎn)換成的sql語句如下:

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

和First和Take相比,缺少了Order子句和Limit子句。掃描的是整個表,獲取的也是表的所有數(shù)據(jù),但因?yàn)榻邮照呤且粋€非切片變量,所以最終只接收了一行數(shù)據(jù)到row中。

我們再來看看給Find傳遞一個切片變量來接收的情況:

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, // 禁用表名復(fù)數(shù)
		}}
	db, _ := gorm.Open(mysql.Open(dsn), config)

	var rows []MTest

	tx.Find(&rows)

	fmt.Printf("rows:%+v\n", rows)
}

這個結(jié)果是接收所有查找到的行的數(shù)據(jù)到rows中。所以大家一定要注意,在使用Find查詢的時候一定要加Where條件和查詢的數(shù)量,以避免掃描和查詢?nèi)淼臄?shù)據(jù),尤其是在大數(shù)量的表中。

六、總結(jié)

本文主要講解了First、Last、Take和Find查詢函數(shù)的不同之處。希望在使用過程中大家根據(jù)自己的應(yīng)用場景選擇合適的函數(shù)。

責(zé)任編輯:武曉燕 來源: 漁夫子
相關(guān)推薦

2010-10-27 10:42:36

oracle FIRS

2021-12-28 20:06:43

JavaScript開發(fā)數(shù)組

2010-10-25 13:48:26

Oracle過程

2010-07-20 09:52:27

Perl構(gòu)造函數(shù)

2010-10-25 17:33:35

Oracle數(shù)學(xué)函數(shù)

2010-10-09 16:11:21

Mysql函數(shù)

2009-06-12 15:36:24

Hibernate fcreateQuery

2025-02-06 13:23:09

C++函數(shù)參數(shù)

2017-08-01 00:19:15

Javascript函數(shù)函數(shù)聲明

2012-05-22 01:52:48

EclipseColorer TakJava

2025-05-20 08:10:00

函數(shù)函數(shù)類型函數(shù)指針類型

2011-05-30 14:30:08

函數(shù)存儲過程

2023-11-29 07:47:29

Golang函數(shù)

2023-08-03 07:40:17

項目樣式查詢

2013-07-30 13:35:12

methodfunction

2010-09-09 11:32:26

SQL函數(shù)StDev

2021-07-30 07:05:31

C語言Memcpy Memmove

2009-03-25 19:28:44

虛擬化Vmware服務(wù)器

2024-05-16 08:37:12

FLIPFirst前端動畫思維

2021-08-04 08:33:59

TypeScriptConst Readonly
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 激情网五月天 | 中文字幕一页二页 | 免费午夜电影 | 欧洲一区二区三区 | 欧洲毛片 | 狠狠的干| 一级全黄视频 | 97久久超碰 | 国产色| 亚洲乱码一区二区三区在线观看 | 成人高清在线 | 亚洲精品电影在线 | 国产乱码精品一品二品 | 欧美理伦片在线播放 | 亚洲欧美精品 | 黄久久久| 亚洲精品性视频 | 午夜视频在线观看网站 | 91社区在线观看 | 精品久久久一区 | 日韩中文在线观看 | 午夜寂寞福利视频 | 日韩免费一区 | 亚洲高清中文字幕 | 免费不卡视频 | 夜夜草导航 | 亚洲天堂久久 | 国产区在线观看 | 午夜羞羞 | 欧美激情 一区 | 国产精品99免费视频 | 久久www免费人成看片高清 | 7777精品伊人久久精品影视 | 国产欧美日韩一区二区三区 | 青青草在线视频免费观看 | 成人三级av | 亚洲顶级毛片 | 欧美 日本 国产 | 男人的天堂久久 | 国产精品1区 | 日韩欧美国产精品综合嫩v 一区中文字幕 |