条件查询是日常开发中最常用的功能。GORM 的
Where方法灵活多样,能满足各种场景需求。
字符串条件:
db.Where("name = ?", "张三").First(&user)
db.Where("age > ?", 20).Find(&users)
db.Where("name <> ?", "张三").Find(&users)
使用占位符 ? 防止 SQL 注入,这是必须遵守的安全规范。
AND 条件:
db.Where("name = ? AND age > ?", "张三", 20).Find(&users)
链式调用自动 AND:
db.Where("name = ?", "张三").Where("age > ?", 20).Find(&users)
OR 条件:
db.Where("name = ?", "张三").Or("name = ?", "李四").Find(&users)
组合 OR:
db.Where("name = ?", "张三").Or(
db.Where("age > ?", 20).Where("status = ?", "active"),
).Find(&users)
db.Where("name IN ?", []string{"张三", "李四", "王五"}).Find(&users)
db.Where("id IN ?", []int{1, 2, 3}).Find(&users)
db.Where("name LIKE ?", "%张%").Find(&users)
db.Where("name LIKE ?", "张%").Find(&users)
db.Where("name LIKE ?", "%三").Find(&users)
db.Where("age BETWEEN ? AND ?", 18, 30).Find(&users)
db.Where("created_at BETWEEN ? AND ?", startTime, endTime).Find(&users)
db.Where("deleted_at IS NULL").Find(&users)
db.Where("email IS NOT NULL").Find(&users)
用结构体作为条件:
db.Where(&User{Name: "张三", Age: 20}).First(&user)
注意:结构体条件会忽略零值。Age: 0 不会被加入查询条件。
用 map 作为条件,零值也会参与:
db.Where(map[string]interface{}{"name": "张三", "age": 0}).Find(&users)
直接传主键:
db.First(&user, 1)
db.Find(&users, []int{1, 2, 3})
db.Not("name", "张三").Find(&users)
db.Not("name IN ?", []string{"张三", "李四"}).Find(&users)
db.Not(map[string]interface{}{"name": "张三", "age": 20}).Find(&users)
db.Where("name = ?", "张三").Or("age > ?", 30).Find(&users)
嵌套 Or:
db.Where(
db.Where("name = ?", "张三").Or("name = ?", "李四"),
).Where("age > ?", 20).Find(&users)
用括号分组:
db.Where("(name = ? OR name = ?) AND age > ?", "张三", "李四", 20).Find(&users)
根据条件动态构建查询:
query := db.Model(&User{})
if name != "" {
query = query.Where("name = ?", name)
}
if minAge > 0 {
query = query.Where("age >= ?", minAge)
}
if maxAge > 0 {
query = query.Where("age <= ?", maxAge)
}
var users []User
query.Find(&users)
实际业务中的复杂查询:
func SearchUsers(db *gorm.DB, params SearchParams) ([]User, error) {
query := db.Model(&User{})
if params.Keyword != "" {
query = query.Where("name LIKE ? OR email LIKE ?",
"%"+params.Keyword+"%",
"%"+params.Keyword+"%")
}
if len(params.Statuses) > 0 {
query = query.Where("status IN ?", params.Statuses)
}
if params.MinAge > 0 {
query = query.Where("age >= ?", params.MinAge)
}
if params.MaxAge > 0 {
query = query.Where("age <= ?", params.MaxAge)
}
if !params.StartTime.IsZero() {
query = query.Where("created_at >= ?", params.StartTime)
}
if !params.EndTime.IsZero() {
query = query.Where("created_at <= ?", params.EndTime)
}
var users []User
return users, query.Find(&users).Error
}
把常用条件封装成函数:
func ActiveUsers(db *gorm.DB) *gorm.DB {
return db.Where("status = ?", "active").Where("deleted_at IS NULL")
}
func AdultUsers(db *gorm.DB) *gorm.DB {
return db.Where("age >= ?", 18)
}
var users []User
ActiveUsers(AdultUsers(db)).Find(&users)
复杂条件直接写 SQL:
db.Where("DATE(created_at) = CURDATE()").Find(&users)
db.Where("YEAR(created_at) = YEAR(NOW())").Find(&users)
条件查询是 GORM 的核心功能。掌握各种条件的写法,能应对大部分业务场景。注意 SQL 注入问题,始终使用占位符。