take 单条记录传入的是结构体,find 多条记录传入的是结构体数组
检索单个对象
GORM 提供了 First
、Take
、Last
方法,以便从数据库中检索单个对象。当查询数据库时它添加了 LIMIT 1
条件,且没有找到记录时,它会返回 ErrRecordNotFound
错误
// 获取第一条记录(主键升序)
db.First(&user)
// SELECT * FROM users ORDER BY id LIMIT 1;
// 获取一条记录,没有指定排序字段
db.Take(&user)
// SELECT * FROM users LIMIT 1;
// 获取最后一条记录(主键降序)
db.Last(&user)
// SELECT * FROM users ORDER BY id DESC LIMIT 1;
result := db.First(&user)
result.RowsAffected // 返回找到的记录数
result.Error // returns error or nil
// 检查 ErrRecordNotFound 错误
errors.Is(result.Error, gorm.ErrRecordNotFound)
如果你想避免
ErrRecordNotFound
错误,你可以使用Find
,比如db.Limit(1).Find(&user)
,Find
方法可以接受struct和slice的数据。find一般不使用
ErrRecordNotFound
错误而是使用RowsAffected
对单个对象使用
Find
而不带limit,db.Find(&user)
将会查询整个表并且只返回第一个对象,这是性能不高并且不确定的。
注意:相对于take first,find不会返回ErrRecordNotFound
错误
var s Student
result := db.Debug().Where("name = ?", "xxx").First(&s)
fmt.Println(result.Error)
[1.926ms] [rows:0] SELECT * FROM `student` WHERE name = 'xxx' ORDER BY `student`.`id` LIMIT 1
record not found
var s Student
result := db.Debug().Take(&s, "name = ?", "xxxx")
fmt.Println(result.Error)
[1.784ms] [rows:0] SELECT * FROM `student` WHERE name = 'xxxx' LIMIT 1
record not found
var s Student
result := db.Debug().Where("name = ?", "xxx").Find(&s)
fmt.Println(result.Error)
[1.706ms] [rows:0] SELECT * FROM `student` WHERE name = 'xxx'
<nil>
var s Student
count := db.Debug().Where("name = ?", "xxx").Find(&s).RowsAffected
fmt.Println(count)
[2.960ms] [rows:0] SELECT * FROM `student` WHERE name = 'xxx'
0
单条记录查询 take(&x) LIMIT 1
//单表记录的查询,
var s Student
db.Debug().Take(&s)
fmt.Println(s)
[1.034ms] [rows:1] SELECT * FROM `students` LIMIT 1
{0 0 false <nil>}
First(&x) Last(&x) ORDER BY 根据id排序取出第一条记录
first就是按照主键排序取第条记录,last就是按照主键倒排,也就是取最后一条记录。
//单表记录的查询
var s Student
db.Take(&Student{})
fmt.Println(s)
[0.505ms] [rows:1] SELECT * FROM `student` LIMIT 1
{1 lucas 29 <nil>}
//因为student结构体里面有数据了,这里要让其清空
s = Student{}
db.Debug().First(&s)
fmt.Println(s)
[0.506ms] [rows:1] SELECT * FROM `students` ORDER BY `students`.`id` LIMIT 1
{0 0 false <nil>}
s = Student{}
db.Debug().Last(&s)
fmt.Println(s)
[0.506ms] [rows:1] SELECT * FROM `students` ORDER BY `students`.`id` DESC LIMIT 1
{0 0 false <nil>}
take(&x , 条件) 条件查询= 获取单条记录
db.Debug().Take(&s, 1)
SELECT * FROM `students` WHERE `students`.`id` = 1 LIMIT 1
db.Debug().Take(&s, "name = ?", "lu")
SELECT * FROM `students` WHERE name = 'lu' LIMIT 1
根据主键的ID查询:
//单表记录的查询,可以使用err去捕获这个异常
var s Student
err := db.Debug().Take(&s, 1).Error
fmt.Println(err == nil)
fmt.Printf("%#v", s)
[1.278ms] [rows:1] SELECT * FROM `students` WHERE `students`.`id` = 1 LIMIT 1
true
main.Student{ID:0x1, Name:"lu", Age:21, Gender:true, Email:(*string)(0xc000209180)}
条件查询:
根据name来查询,这里一定要使用?去进行一个拼接,这个数值可能是前端传递过来的。
//单表记录的查询,可以使用err去捕获这个异常
var s Student
err := db.Debug().Take(&s, "name = ?", "lu").Error
fmt.Println(err == nil)
fmt.Printf("%#v", s)
[0.616ms] [rows:1] SELECT * FROM `students` WHERE name = 'lu' LIMIT 1
true
main.Student{ID:0x1, Name:"lu", Age:21, Gender:true, Email:(*string)(0xc0001cb230)}
或者
db.Take(&s, fmt.Sprintf("name = '%s'", "lu"))
fmt.Printf("%#v", s)
Find 查询所有记录 获取多条记录 find等价于select * from table
db.Debug().Find(&s)
SELECT * FROM `students`
查询多条记录,将其变为切片就行了。
var s []Student
db.Debug().Find(&s)
fmt.Printf("%#v", s)
for _, v := range s {
fmt.Println(v)
}
type Student struct {
ID uint `gorm:"size:3" json:"id"`
Name string `gorm:"size:3" json:"name"`
Age int `gorm:"size:3" json:"age"`
Gender bool
Email *string `gorm:"size:32" json:"email"`
}
var s []Student
count := db.Debug().Find(&s).RowsAffected
fmt.Println(count)
for _, v := range s {
fmt.Println(v)
data, _ := json.Marshal(v)
fmt.Println(string(data))
}
[0.889ms] [rows:25] SELECT * FROM `students`
25
{1 lu 21 true 0xc0001cb270}
{"id":1,"name":"lu","age":21,"Gender":true,"email":"123@qq.com"}
因为指针id是看不懂的,通过json转化就可以变为看的懂的。
Find查询指定的记录 = 获取多条记录
var SList []Student
count := db.Debug().Find(&SList, "name = ?", "yanzi").RowsAffected
fmt.Println(count)
for _, v := range SList {
data, _ := json.Marshal(v)
fmt.Println(string(data))
}
[2.167ms] [rows:4] SELECT * FROM `student` WHERE name = 'yanzi'
4
{"ID":10,"Name":"yanzi","Age":28,"Email":"1239683670@qq.com"}
{"ID":11,"Name":"yanzi","Age":28,"Email":"1239683670@qq.com"}
{"ID":13,"Name":"yanzi","Age":28,"Email":"1239683670@qq.com"}
{"ID":15,"Name":"yanzi","Age":28,"Email":"1239683670@qq.com"}
Find 条件查询指定记录集合 in 获取多条记录
db.Debug().Find(&s, []int{1, 3, 5})SELECT * FROM `student` WHERE `student`.`id` IN (1,3,5)
db.Debug().Find(&s, "name in ?", []string{"lucas", "hello"})SELECT * FROM `student` WHERE name in ('lucas','hello')
var s []Student
count := db.Debug().Find(&s, []int{1, 2, 3}).RowsAffected
fmt.Println(count, s)
[4.537ms] [rows:3] SELECT * FROM `students` WHERE `students`.`id` IN (1,2,3)
3 [{1 lu 21 true 0xc00020a0b0} {2 21 true <nil>} {3 21 true <nil>}]