Skip to main content

Querying

表查询

单个对象

Gorm提供了FirstTakeLast方法,以便从数据库中检索单个对象。当查询数据库时它添加了LIMIT 1条件,且没有找到记录时,会返回ErrRecordNotFound错误。

var stu Student

// 获取第一条记录(主键升序)
db.First(&stu)

// 获取最后一条记录(主键降序)
db.Last(&stu)

// 获取一条记录,没有指定排序字段
db.Take(&stu)

如果想避免ErrRecordNotFound错误,可以使用Find,比如db.Limit(1).Find(&stu),Find方法可以接受structslice的数据。

FirstLast方法会按主键排序找到第一条记录和最后一条记录。只有在目标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方法中一样内联到FirstFind等方法中:

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)

当然,structmap作为条件的情况同样适用。

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;