GORM 的典型查询示例

以下是一些 GORM 的典型查询示例,涵盖了常见的数据库操作场景:


1. 基本查询

// 定义模型
type User struct {
    gorm.Model
    Name  string
    Age   int
    Email string
}

// 根据主键查询第一条记录
var user User
result := db.First(&user) // SELECT * FROM users ORDER BY id LIMIT 1;
if result.Error != nil {
    // 处理错误
}

// 查询所有记录
var users []User
db.Find(&users) // SELECT * FROM users;

// 根据主键查询特定记录
db.First(&user, 10) // SELECT * FROM users WHERE id = 10;

2. 条件查询

// WHERE 条件
db.Where("name = ?", "Alice").First(&user)
// SELECT * FROM users WHERE name = 'Alice' ORDER BY id LIMIT 1;

// 结构体条件
db.Where(&User{Name: "Bob", Age: 20}).Find(&users)
// SELECT * FROM users WHERE name = 'Bob' AND age = 20;

// Map 条件
db.Where(map[string]interface{}{"age": 30}).Find(&users)
// SELECT * FROM users WHERE age = 30;

// IN 查询
db.Where("age IN ?", []int{20, 25, 30}).Find(&users)
// SELECT * FROM users WHERE age IN (20, 25, 30);

// LIKE 查询
db.Where("name LIKE ?", "%john%").Find(&users)
// SELECT * FROM users WHERE name LIKE '%john%';

3. 预加载关联(Eager Loading)

type Order struct {
    gorm.Model
    UserID  uint
    Product string
}

// 预加载 User 关联
var orders []Order
db.Preload("User").Find(&orders)
// SELECT * FROM orders;
// SELECT * FROM users WHERE id IN (order1.user_id, order2.user_id, ...);

4. 选择字段 & 排序 & 分页

// 选择特定字段
db.Select("name", "age").Find(&users)
// SELECT name, age FROM users;

// 排序
db.Order("age desc").Find(&users) // 按年龄降序

// 分页
page := 1
pageSize := 10
db.Offset((page - 1) * pageSize).Limit(pageSize).Find(&users)
// SELECT * FROM users OFFSET 0 LIMIT 10;

5. 更新操作

// 更新单个字段
db.Model(&user).Update("name", "Alice")
// UPDATE users SET name = 'Alice' WHERE id = user.id;

// 更新多个字段
db.Model(&user).Updates(User{Name: "Bob", Age: 30})
// UPDATE users SET name = 'Bob', age = 30 WHERE id = user.id;

// 使用 Map 更新
db.Model(&user).Updates(map[string]interface{}{"name": "Charlie", "age": 25})

// 更新所有匹配记录
db.Where("age < ?", 18).Updates(User{Age: 18})
// UPDATE users SET age = 18 WHERE age < 18;

6. 删除操作

// 删除记录
db.Delete(&user) // 软删除(如果模型有 DeletedAt 字段)
// UPDATE users SET deleted_at = NOW() WHERE id = user.id;

// 硬删除
db.Unscoped().Delete(&user)
// DELETE FROM users WHERE id = user.id;

// 批量删除
db.Where("age < ?", 18).Delete(&User{})
// DELETE FROM users WHERE age < 18;

7. 原生 SQL 查询

// 执行原生 SQL
var users []User
db.Raw("SELECT * FROM users WHERE age > ?", 25).Scan(&users)

// 使用 Exec 执行非查询操作
db.Exec("UPDATE users SET name = ? WHERE id = ?", "David", 100)

8. 链式操作

// 链式条件查询
query := db.Where("name LIKE ?", "%john%")
if minAge > 0 {
    query = query.Where("age >= ?", minAge)
}
query.Find(&users)

9. 事务处理

// 手动事务
tx := db.Begin()
defer func() {
    if r := recover(); r != nil {
        tx.Rollback()
    }
}()

if err := tx.Create(&user).Error; err != nil {
    tx.Rollback()
    return err
}

if err := tx.Model(&order).Update("status", "paid").Error; err != nil {
    tx.Rollback()
    return err
}

tx.Commit()

10. 高级查询

// 子查询
subQuery := db.Select("AVG(age)").Where("name LIKE ?", "%john%").Table("users")
db.Select("AVG(age) as avg_age").Group("name").Having("AVG(age) > (?)", subQuery).Find(&result)

// 关联计数
var user User
db.Model(&user).Association("Orders").Count()

// 使用 Scopes 复用查询逻辑
func AgeGreaterThan(age int) func(db *gorm.DB) *gorm.DB {
    return func(db *gorm.DB) *gorm.DB {
        return db.Where("age > ?", age)
    }
}

db.Scopes(AgeGreaterThan(20)).Find(&users)

这些示例覆盖了 GORM 的大部分常见查询场景。实际使用时,请根据需求结合错误处理(如检查 result.Error)和模型定义进行调整。GORM 的链式调用和灵活的查询构造使其非常适合复杂业务逻辑的实现。

posted @ 2025-04-01 21:00  许仙儿  阅读(65)  评论(1)    收藏  举报