package datasource import ( "servicebase/pkg/log" "servicebase/pkg/repo" "servicebase/pkg/utils" "strings" "time" "github.com/spf13/viper" "gorm.io/driver/mysql" "gorm.io/gorm" "gorm.io/gorm/schema" "gorm.io/plugin/dbresolver" ) type BaseModel struct { ID int `gorm:"primaryKey" json:"id"` CreateTime utils.Time `gorm:"type:datetime;index;not null" json:"createTime"` } func (model *BaseModel) BeforeCreate(tx *gorm.DB) (err error) { model.CreateTime.Time = time.Now() return } var DB *gorm.DB type MySQLStarter struct { } func (s *MySQLStarter) Init() error { InitMySQl() return nil } func InitMySQl() { dsn := viper.GetString("db.connectString") log.InfoF("init db config with: %s", dsn) var e error if DB, e = gorm.Open(mysql.New(mysql.Config{ DriverName: "", ServerVersion: "", DSN: dsn, Conn: nil, SkipInitializeWithVersion: false, DefaultStringSize: 255, DefaultDatetimePrecision: nil, DisableDatetimePrecision: true, DontSupportRenameIndex: false, DontSupportRenameColumn: true, DontSupportForShareClause: false, // DontSupportNullAsDefaultValue: false, }), &gorm.Config{ SkipDefaultTransaction: false, NamingStrategy: schema.NamingStrategy{ TablePrefix: "", // table name prefix, table for `User` would be `t_users` SingularTable: true, // use singular table name, table for `User` would be `user` with this option enabled NoLowerCase: false, // skip the snake_casing of names NameReplacer: strings.NewReplacer("PID", "pid"), // use name replacer to change struct/field name before convert it to db name }, FullSaveAssociations: false, Logger: &log.GLog{}, // NowFunc: func() time.Time { return time.Now().Local() }, DryRun: false, PrepareStmt: false, // 执行任何 SQL 时都会创建一个 prepared statement 并将其缓存,以提高后续的效率 DisableAutomaticPing: false, // 在完成初始化后,GORM 会自动 ping 数据库以检查数据库的可用性 DisableForeignKeyConstraintWhenMigrating: true, // 在 AutoMigrate 或 CreateTable 时,GORM 会自动创建外键约束,若要禁用该特性,可将其设置为 true DisableNestedTransaction: false, // 嵌套事务 AllowGlobalUpdate: false, // true = 启用全局 update/delete QueryFields: false, CreateBatchSize: 0, ClauseBuilders: nil, ConnPool: nil, Dialector: nil, Plugins: nil, }); e != nil { panic("failed to connect database") } _ = DB.Use(dbresolver.Register(dbresolver.Config{ Replicas: []gorm.Dialector{mysql.Open(dsn)}, Policy: dbresolver.RandomPolicy{}, }).Register(dbresolver.Config{ Replicas: []gorm.Dialector{mysql.Open(dsn)}, } /* &model.User{} */)) sqlDB, _ := DB.DB() // SetMaxIdleConns 用于设置连接池中空闲连接的最大数量。 sqlDB.SetMaxIdleConns(20) // SetMaxOpenConns 设置打开数据库连接的最大数量。 sqlDB.SetMaxOpenConns(100) // SetConnMaxLifetime 设置了连接可复用的最大时间。 sqlDB.SetConnMaxLifetime(time.Hour * 24) // log.InfoF("gorm metrics at: %d", viper.GetUint32("db.metrics.port")) // _ = DB.Use(prometheus.New(prometheus.Config{ // DBName: "db_data-front", // 使用 `DBName` 作为指标 label // RefreshInterval: 10, // 指标刷新频率(默认为 15 秒) // PushAddr: "", // 如果配置了 `PushAddr`,则推送指标 // StartServer: false, // 启用一个 http 服务来暴露指标 // //HTTPServerPort: viper.GetUint32("db.metrics.port"), // 配置 http 服务监听端口,默认端口为 8080 (如果您配置了多个,只有第一个 `HTTPServerPort` 会被使用) // MetricsCollector: []prometheus.MetricsCollector{ // &prometheus.MySQL{ // // 指标名前缀,默认为 `gorm_status_` // // 例如: Threads_running 的指标名就是 `gorm_status_Threads_running` // Prefix: "gorm_status_", // // 拉取频率,默认使用 Prometheus 的 RefreshInterval // Interval: 30, // // 从 SHOW STATUS 选择变量变量,如果不设置,则使用全部的状态变量 // VariableNames: []string{"Threads_running"}, // }, // }, // 用户自定义指标 // })) //_ = DB.Use(tracing.NewPlugin(tracing.WithoutMetrics())) autoMigrate() repo.SetDefault(DB) } func autoMigrate() { //_ = DB.AutoMigrate(&model.User{}) //_ = DB.AutoMigrate(&model.LeaseType{}) }