复盘orm库gorm框架

gorm是一个使用Go语言编写的ORM框架。它文档齐全,对开发者友好,支持主流数据库。
基础配置

type DbConfig struct {
    DbHost        string `mapstructure:"db_host" json:"db_host" yaml:"db_host"`
    DbPort        int    `mapstructure:"db_port" json:"db_port" yaml:"db_port"`
    DbName        string `mapstructure:"db_name" json:"db_name" yaml:"db_name"`
    DbUser        string `mapstructure:"db_user" json:"db_user" yaml:"db_user"`
    DbPass        string `mapstructure:"db_pass" json:"db_pass" yaml:"db_pass"`
    TablePrefix   string `mapstructure:"table_prefix" json:"table_prefix" yaml:"table_prefix"`
    TimeZone      string `mapstructure:"time_zone" json:"time_zone" yaml:"time_zone"`
    LogLevel      int    `mapstructure:"log_level" json:"log_level" yaml:"log_level"`                // LogLevel SQL日志级别 (1-静音 2-错误 3-警告 4-信息)
    SlowThreshold int    `mapstructure:"slow_threshold" json:"slow_threshold" yaml:"slow_threshold"` // SlowThreshold 慢SQL阈值(毫秒)。慢SQL会在log_level大于等于3时输出。
    IdleConns     int    `mapstructure:"idle_conns" json:"idle_conns" yaml:"idle_conns"`             // 空闲连接池中的最大连接数,建议为open_conns的百分之5-20之间
    OpenConns     int    `mapstructure:"open_conns" json:"open_conns" yaml:"open_conns"`             // 最大打开连接数,建议这里设置为50
}

func InitGorm(conf *config.Config) *gorm.DB {
    dsn := fmt.Sprintf("host=%s port=%d dbname=%s user=%s password=%s sslmode=disable TimeZone=%s",
        conf.Db.DbHost, conf.Db.DbPort, conf.Db.DbName, conf.Db.DbUser, conf.Db.DbPass, conf.Db.TimeZone)
    postgresConfig := postgres.Config{
        DSN:                  dsn,  // DSN data source name
        PreferSimpleProtocol: true, // 禁用隐式 prepared statement
    }

    // 使用标准日志库的New方法创建日志输出
    //newLogger := logger.New(
    //  log.New(os.Stdout, "\r\n", log.LstdFlags),
    //  logger.Config{
    //      SlowThreshold:             time.Duration(dbConf.SlowThreshold) * time.Millisecond, // 慢SQL阈值
    //      LogLevel:                  logger.LogLevel(dbConf.LogLevel),                       // 日志级别
    //      IgnoreRecordNotFoundError: true,
    //      Colorful:                  true,
    //  })

    // zap 自定义
    newLogger := NewGormLogger(x_logger.GormZapLog.GetZapLogger(), logger.LogLevel(conf.Db.LogLevel))

    PGDB, err := gorm.Open(postgres.New(postgresConfig), &gorm.Config{
        //Logger: newLogger,
        //Logger: logger.Default.LogMode(logger.Info),
        Logger: newLogger,
        NamingStrategy: schema.NamingStrategy{
            SingularTable: false, // 使用单数表名,在启用此选项的情况下,“user”的表将是“user”
            TablePrefix:   "te_", // 表前缀
        },
    })

    DB := PGDB

    if err != nil {
        fmt.Println("数据库链接失败")
        os.Exit(0)
    }
    AutoMigrate(DB)
    sqlDB, _ := DB.DB()
    sqlDB.SetMaxIdleConns(conf.Db.IdleConns)
    sqlDB.SetMaxOpenConns(conf.Db.OpenConns)
    // 设置数据库连接池中连接的最大生命周期
    sqlDB.SetConnMaxLifetime(time.Hour)
    fmt.Println("[+]PG连接成功!")
    return DB
}

// AutoMigrate 自动迁移
func AutoMigrate(db *gorm.DB) {
    err := db.AutoMigrate(
        new(model.User),
    )
    if err != nil {
        fmt.Println("[-] 迁移数据表失败:", err.Error())
        os.Exit(0)
    }
}

基础的数据操作

    // 获取表名
    m := &model.User{}
    modelType := reflect.TypeOf(m).Elem()
    fmt.Println(modelType)
    tableName := global.Db.NamingStrategy.TableName("User")
    fmt.Println(tableName)
    //
    // 插入一条记录
    user := model.User{Name: "刘建超"}
    result := global.Db.Create(&user) // 在数据库中插入一条新记录
    fmt.Println(result.Error)         // 如果有错误,打印错误
    fmt.Println(user.ID)              // 打印插入后生成的 ID
    fmt.Printf("%#v", user)           // 打印插入后生成的 ID

    // Save 修改记录
    user = model.User{Name: "刘建超iuu"}
    user.ID = 1
    // 排除指定字段
    global.Db.Omit("Created").Save(&user)

    // 软删除
    global.Db.Delete(&user)

    // 如果主键为空,插入新记录
    user = model.User{Name: "iuu"}
    global.Db.Save(&user)

    user = model.User{Name: "刘建超iuuxxx"}
    user.ID = 2
    global.Db.Select("Name").Save(&user)

    //永久删除
    global.Db.Unscoped().Delete(&user)