Querying
表查询
单个对象
Gorm提供了First、Take、Last方法,以便从数据库中检索单个对象。当查询数据库时它添加了LIMIT 1条件,且没有找到记录时,会返回ErrRecordNotFound错误。
var stu Student
// 获取第一条记录(主键升序)
db.First(&stu)
// 获取最后一条记录(主键降序)
db.Last(&stu)
// 获取一条记录,没有指定排序字段
db.Take(&stu)
如果想避免ErrRecordNotFound错误,可以使用Find,比如db.Limit(1).Find(&stu),Find方法可以接受struct和slice的数据。
First和Last方法会按主键排序找到第一条记录和最后一条记录。只有在目标struct是指针或者通过db.Model()指定 model 时,该方法才有效。如果相关model没有定义主键,那么将按model的第一个字段进行排序。
stu := map[string]interface{}{}
db.Model(&Student{}).First(&stu)
fmt.Println(stu)
主键查询
var stu Student
db.First(&stu, 15)
// SELECT * FROM Students WHERE id = 15;
db.Find(&stu, []int{10, 11, 12})
// SELECT * FROM students WHERE id IN (10, 11, 12);
db.First(&stu, "id = ?", "16")
// SELECT * FROM users WHERE id = "16";
查询全部
可使用Find来查询全部记录:
var stus []Student
db.Find(&stus)
fmt.Println(stus)
String条件
var stu Student
var stus []Student
// 等于
db.Where("name = ?", "Lisa1").First(&stu)
// 不等于
db.Where("name <> ?", "Lisa1").First(&stu)
// IN
db.Where("name IN ?", []string{"Lisa1", "Tom"}).First(&stu)
// LIKE
db.Where("name LIKE ?", "%Lisa%").Find(&stus)
// AND
db.Where("name LIKE ? and age > ?", "%Lisa%", 22).Find(&stus)
// BETWEEN
db.Where("age BETWEEN ? and ?", 17, 21).Find(&stus)
如果对象设置了主键,条件查询将不会覆盖主键的值,而是用And连接条件:
var stu = Student{ID: 10}
db.Where("id = ?", 20).First(&stu)
// SELECT * FROM students WHERE id = 10 and id = 20 ORDER BY id ASC LIMIT 1
struct条件
可将struct作为Where查询条件:
var stus []Student
db.Where(&Student{Name: "Lisa", Age: 20}).Find(&stus)
// SELECT * FROM students WHERE name = "Lisa" and age = 20 ORDER BY id LIMIT 1;
但是使用结构体作为查询条件时,只会查询非零值字段,这意味着如果某个查询字段的值是0、``,false或其他零值,将不会作为查询条件:
db.Where(&Student{Name: "Lisa", Age: 0}).Find(&stus)
// SELECT * FROM students WHERE name = "Lisa" ORDER BY id LIMIT 1;
为了避免如上问题,可使用map条件查询。
结构体指定字段
使用结构体作为查询条件时可指定查询字段,如果结构体中没有指定的字段,则使用零值:
db.Where(&Student{Name: "Lisa"}, "name", "age").Find(&stus)
// SELECT * FROM students WHERE name = "Lisa" AND age = 0;
map条件
可将map作为Where查询条件:
var stus []Student
// db.Model(&Student{}).Where(map[string]interface{}{"name": "Lisa"}).Find(&stus)
db.Where(map[string]interface{}{"name": "Lisa"}).Find(&stus)
// SELECT * FROM students WHERE name = "Lisa";
slice条件
可使用slice将主键作为条件:
db.Where([]int64{20, 21, 22}).Find(&stus)
// SELECT * FROM students WHERE id IN (20, 21, 22);
内联查询
查询条件可以像在Where方法中一样内联到First、Find等方法中:
db.Find(&stus, "name LIKE ? and age > ?", "%Lisa%", 22)
// struct
db.Find(&stus, Student{Name: "Lisa"})
// map
db.Find(&stus, map[string]interface{}{"name": "Lisa"})
Not
构建NOT条件,类似于Where方法的工作方式:
db.Not("name LIKE ? and age > ?", "%Lisa%", 22).Find(&stus)
// struct
db.Not(&Student{Name: "Lisa"}).Find(&stus)
// map
db.Not(&Student{}).Where(map[string]interface{}{"name": "Lisa"}).Find(&stus)
Or
db.Where("name = ?", "Lisa").Or("age = ?", 23).Find(&stus)
// SELECT * FROM users WHERE name = 'Lisa' OR age = 23
db.Where("name = ?", "Lisa").Or("age = ?", 23).Or("name LIKE ?", "%Jack%").Find(&stus)
当然,struct及map作为条件的情况同样适用。
Select
Select允许指定要从数据库中检索的字段,否则,Gorm默认会选择所有字段:
db.Where("name LIKE ?", "%Lisa%").Select("name").Find(&stus)
db.Select([]string{"name", "age"}).Find(&stus)
Order
指定在从数据库中检索记录时的排序顺序:
db.Order("age desc").Find(&stus)
// SELECT * FROM students ORDER BY age desc;