package connection import ( config "common/configsYaml" "common/rabbitmq" "gorm.io/gorm" "goutil/logUtilPlus" "strconv" "time" ) var ( // 存放实体结构 dbModelMap = make([]interface{}, 0) //当前管理数据库 modelDB *gorm.DB ) func init() { // 启动异步处理 go ExecuteCreateChan() go ExecuteSaveChan() go ExecuteDeleteChan() } // RegisterDBModel 注册数据库模型到全局变量dbModelMap中。 // 这个函数接受一个interface{}类型的参数dbModel,表示数据库模型。 // 函数的目的是将传入的数据库模型添加到全局变量dbModelMap中, // 以便在其他地方可以访问和使用这些数据库模型。 func RegisterDBModel(dbModel interface{}) { // 将dbModel的地址添加到dbModelMap中。 // 这里使用地址是因为数据库模型可能比较大,通过引用存储可以提高效率。 dbModelMap = append(dbModelMap, &dbModel) } // SetModelDB 设置modelDB 类型 func SetModelDB(db *gorm.DB) { modelDB = db } // BuildDB 用于遍历dbModelMap中的所有数据库模型,并检查每个模型对应的表是否存在于数据库中。 // 如果表不存在,则自动迁移(创建)该表。这样可以确保数据库模式与程序中的模型保持同步。 func BuildDB() { // 遍历dbModelMap中的每个元素 for _, dbModel := range dbModelMap { // 检查数据库中是否存在与dbModel对应的表 CheckTableExists(modelDB, dbModel) } } // CheckTableExists 检查表是否存在,不存在则添加 func CheckTableExists(db *gorm.DB, value interface{}) bool { // 检查数据库中是否存在与dbModel对应的表 tableExists := db.Migrator().HasTable(value) if !tableExists { // 如果表不存在,则进行自动迁移 err := db.AutoMigrate(value) if err != nil { logUtilPlus.ErrorLog("CheckTableExists is err: %v", err.Error()) return false } } return true } // GetMonth 获取当前月份 func GetMonth() int32 { month, err := strconv.Atoi(time.Now().Format("200601")) if err != nil { logUtilPlus.ErrorLog("GetMonth is err: %v", err.Error()) return 0 } return int32(month) } // GetToMonthAdd 获取当前月份 加上指定个月 func GetToMonthAdd(monthCount int32) int32 { month, err := strconv.Atoi(time.Now().AddDate(0, int(monthCount), 0).Format("200601")) if err != nil { logUtilPlus.ErrorLog("GetToMonthAdd is err: %v", err.Error()) return 0 } return int32(month) } // Create 添加数据 // @param db 数据库连接 // @param value 值 // @param dbIndex mq队列索引 func Create(db *gorm.DB, value interface{}, dbIndex int32) *gorm.DB { result := &gorm.DB{Error: nil} //检查表是否存在 CheckTableExists(db, value) //转换sql mq远程执行 if config.GetSqlUseMQ() { sql := db.ToSQL(func(tx *gorm.DB) *gorm.DB { return tx.Model(value).Create(value) }) //推送数据到mq rabbitmq.SendMqData(dbIndex, sql) //直接返回 return result } result = db.Create(value) if result.Error != nil { logUtilPlus.ErrorLog("数据创建失败:", result.Error.Error()) } return result } // Save 保存数据 func Save(db *gorm.DB, value interface{}, dbIndex int32) *gorm.DB { result := &gorm.DB{Error: nil} //转换sql mq远程执行 if config.GetSqlUseMQ() { sql := db.ToSQL(func(tx *gorm.DB) *gorm.DB { return tx.Model(value).Save(value) }) //推送数据到mq rabbitmq.SendMqData(dbIndex, sql) return result } result = db.Save(value) if result.Error != nil { logUtilPlus.ErrorLog("数据保存失败:", result.Error.Error()) } return result } // DBData 添加数据通道 type DBData struct { DB *gorm.DB Value any } var ( // 添加数据通道 createChan = make(chan DBData) // 保存数据通道 saveChan = make(chan DBData) // 删除数据通道 deleteChan = make(chan DBData) ) // AsyncCreate 异步创建数据 func AsyncCreate(db *gorm.DB, value interface{}) { createChan <- DBData{ DB: db, Value: value, } } // ExecuteCreateChan 执行添加数据通道 func ExecuteCreateChan() { defer func() { if err := recover(); err != nil { logUtilPlus.ErrorLog("AsyncCreate is err: %v", err) //停止程序 panic(err) } }() for { select { case createData := <-createChan: db := createData.DB value := createData.Value //检查表是否存在 CheckTableExists(db, value) result := db.Create(value) if result.Error != nil { logUtilPlus.ErrorLog("AsyncCreate is err: %v", result.Error) } } } } // AsyncSave 异步保存数据 func AsyncSave(db *gorm.DB, value interface{}) { saveChan <- DBData{ DB: db, Value: value, } } // ExecuteSaveChan 执行保存数据通道 func ExecuteSaveChan() { defer func() { if err := recover(); err != nil { logUtilPlus.ErrorLog("AsyncSave is err: %v", err) panic(err) } }() for { select { case saveData := <-saveChan: db := saveData.DB value := saveData.Value result := db.Save(value) if result.Error != nil { logUtilPlus.ErrorLog("AsyncSave is err : %v", result.Error) } } } } // AsyncDelete 异步删除数据 func AsyncDelete(db *gorm.DB, value interface{}) { deleteChan <- DBData{ DB: db, Value: value, } } // ExecuteDeleteChan 执行删除数据通道 func ExecuteDeleteChan() { defer func() { if err := recover(); err != nil { logUtilPlus.ErrorLog("AsyncDelete is err: %v", err) panic(err) } }() for { select { case deleteData := <-deleteChan: db := deleteData.DB value := deleteData.Value result := db.Delete(value) if result.Error != nil { logUtilPlus.ErrorLog("AsyncDelete is err : %v", result.Error) } } } }