GORM集成 #

一、安装配置 #

1.1 安装依赖 #

bash
go get -u gorm.io/gorm
go get -u gorm.io/driver/postgres

1.2 数据库连接 #

go
package database

import (
    "gorm.io/driver/postgres"
    "gorm.io/gorm"
    "gorm.io/gorm/logger"
)

func Connect(dsn string) (*gorm.DB, error) {
    return gorm.Open(postgres.Open(dsn), &gorm.Config{
        Logger: logger.Default.LogMode(logger.Info),
    })
}

二、模型定义 #

2.1 基本模型 #

go
package models

import (
    "time"
    "gorm.io/gorm"
)

type User struct {
    ID        string         `gorm:"primaryKey"`
    Name      string         `gorm:"size:100;not null"`
    Email     string         `gorm:"size:255;uniqueIndex;not null"`
    Password  string         `gorm:"size:255;not null"`
    Age       int            `gorm:"default:0"`
    Active    bool           `gorm:"default:true"`
    CreatedAt time.Time
    UpdatedAt time.Time
    DeletedAt gorm.DeletedAt `gorm:"index"`
}

func (u *User) BeforeCreate(tx *gorm.DB) error {
    if u.ID == "" {
        u.ID = uuid.New().String()
    }
    return nil
}

2.2 关联模型 #

go
type User struct {
    ID      string  `gorm:"primaryKey"`
    Name    string  `gorm:"size:100"`
    Posts   []Post  `gorm:"foreignKey:UserID"`
    Profile Profile `gorm:"foreignKey:UserID"`
}

type Post struct {
    ID        string    `gorm:"primaryKey"`
    Title     string    `gorm:"size:255"`
    Content   string    `gorm:"type:text"`
    UserID    string    `gorm:"index"`
    User      User
    Comments  []Comment `gorm:"foreignKey:PostID"`
}

type Comment struct {
    ID      string `gorm:"primaryKey"`
    Content string `gorm:"type:text"`
    PostID  string `gorm:"index"`
    Post    Post
}

type Profile struct {
    ID     string `gorm:"primaryKey"`
    Bio    string `gorm:"type:text"`
    UserID string `gorm:"uniqueIndex"`
    User   User
}

三、CRUD操作 #

3.1 创建 #

go
func CreateUser(db *gorm.DB, user *models.User) error {
    return db.Create(user).Error
}

// 批量创建
func CreateUsers(db *gorm.DB, users []models.User) error {
    return db.Create(&users).Error
}

3.2 查询 #

go
// 单条查询
func GetUserByID(db *gorm.DB, id string) (*models.User, error) {
    var user models.User
    err := db.First(&user, "id = ?", id).Error
    return &user, err
}

// 条件查询
func GetActiveUsers(db *gorm.DB) ([]models.User, error) {
    var users []models.User
    err := db.Where("active = ?", true).Find(&users).Error
    return users, err
}

// 分页查询
func GetUsersPaginated(db *gorm.DB, page, limit int) ([]models.User, int64, error) {
    var users []models.User
    var total int64
    
    db.Model(&models.User{}).Count(&total)
    
    offset := (page - 1) * limit
    err := db.Offset(offset).Limit(limit).Find(&users).Error
    
    return users, total, err
}

3.3 更新 #

go
// 更新单个字段
func UpdateUserActive(db *gorm.DB, id string, active bool) error {
    return db.Model(&models.User{}).Where("id = ?", id).Update("active", active).Error
}

// 更新多个字段
func UpdateUser(db *gorm.DB, user *models.User) error {
    return db.Save(user).Error
}

// 选择性更新
func UpdateUserFields(db *gorm.DB, id string, fields map[string]interface{}) error {
    return db.Model(&models.User{}).Where("id = ?", id).Updates(fields).Error
}

3.4 删除 #

go
// 软删除
func DeleteUser(db *gorm.DB, id string) error {
    return db.Delete(&models.User{}, "id = ?", id).Error
}

// 永久删除
func ForceDeleteUser(db *gorm.DB, id string) error {
    return db.Unscoped().Delete(&models.User{}, "id = ?", id).Error
}

四、关联查询 #

4.1 预加载 #

go
// 加载关联
func GetUserWithPosts(db *gorm.DB, id string) (*models.User, error) {
    var user models.User
    err := db.Preload("Posts").First(&user, "id = ?", id).Error
    return &user, err
}

// 嵌套预加载
func GetUserWithPostsAndComments(db *gorm.DB, id string) (*models.User, error) {
    var user models.User
    err := db.Preload("Posts.Comments").First(&user, "id = ?", id).Error
    return &user, err
}

五、事务 #

5.1 手动事务 #

go
func TransferMoney(db *gorm.DB, fromID, toID string, amount float64) error {
    tx := db.Begin()
    defer func() {
        if r := recover(); r != nil {
            tx.Rollback()
        }
    }()
    
    if err := tx.Model(&Account{}).Where("id = ?", fromID).Update("balance", gorm.Expr("balance - ?", amount)).Error; err != nil {
        tx.Rollback()
        return err
    }
    
    if err := tx.Model(&Account{}).Where("id = ?", toID).Update("balance", gorm.Expr("balance + ?", amount)).Error; err != nil {
        tx.Rollback()
        return err
    }
    
    return tx.Commit().Error
}

5.2 自动事务 #

go
func CreateUserWithProfile(db *gorm.DB, user *models.User, profile *models.Profile) error {
    return db.Transaction(func(tx *gorm.DB) error {
        if err := tx.Create(user).Error; err != nil {
            return err
        }
        
        profile.UserID = user.ID
        if err := tx.Create(profile).Error; err != nil {
            return err
        }
        
        return nil
    })
}

六、总结 #

6.1 GORM常用方法 #

方法 说明
Create 创建记录
First 查询单条
Find 查询多条
Save 保存更新
Delete 删除记录
Preload 预加载关联

6.2 下一步 #

现在你已经掌握了GORM集成,接下来让我们学习 Redis集成,了解缓存使用!

最后更新:2026-03-28