Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Suggestions on how to process files after gf gen dao in database tables, it has been tested and feasible #3546

Open
lengyuhen opened this issue Apr 26, 2024 · 0 comments

Comments

@lengyuhen
Copy link

Description

1、分表根据玩家uid%10获得表id,如 game_best_0,game_best_1,game_best_2,.......,game_best_9,共10张表,gf gen dao 生成四份go文件,只修改2份文件,这些表规律是从0到M,共M+1张表,逐步+1,所以将uid作为参数传入,现在可使用gf gen dao的数据库下创建同字段的game_best_,然后修改下列两个文件,删除game_best_表,防止重新生成覆盖

以下为例子

./internal/dao/internal/game_best.go

package internal

import (
"context"
"strconv"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/text/gstr"
)

// GameBestDao is the data access object for table game_best.
type GameBestDao struct {
table string // table is the underlying table name of the DAO.
group string // group is the database configuration group name of current DAO.
columns GameBestColumns // columns contains all the column names of Table for convenient usage.
tableCount int //分表个数
}

// GameBestColumns defines and stores column names for table game_best.
type GameBestColumns struct {
Uid string // 玩家id
Money string // 游戏币
Diamond string // 钻石
Score string // 积分
Exp string // 经验
Coin string // 现金币
Gcoin string // 黄金币
}

// gameBestColumns holds the columns for table game_best.
var gameBestColumns = GameBestColumns{
Uid: "uid",
Money: "money",
Diamond: "diamond",
Score: "score",
Exp: "exp",
Coin: "coin",
Gcoin: "gcoin",
}

// NewGameBestDao creates and returns a new DAO object for table data access.
func NewGameBestDao() *GameBestDao {
return &GameBestDao{
group: "gamebest",
table: "game_best_",//除去末端数字余下部分
columns: gameBestColumns,
tableCount: 10, //生成时候先算下分了多少表
}
}

// DB retrieves and returns the underlying raw database management object of current DAO.
func (dao *GameBestDao) DB() gdb.DB {
return g.DB(dao.group)
}

// Table returns the table name of current dao.
func (dao *GameBestDao) Table() string {
return dao.table
}

// Columns returns all column names of current dao.
func (dao *GameBestDao) Columns() GameBestColumns {
return dao.columns
}

// Group returns the configuration group name of database of current dao.
func (dao *GameBestDao) Group() string {
return dao.group
}

// 获取分表个数
func (dao *GameBestDao) TableCount() int {
return dao.tableCount
}

// 处理分表,恢复实际表名
func (dao *GameBestDao) setTable(uid int) string {
var (
remainder = uid % dao.tableCount
str = strconv.Itoa(remainder)
array = []string{dao.table, str}
result = gstr.Join(array, ``)
)
return result
}

// 改造后添加分表,按uid分表,作为传参
// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation.
func (dao *GameBestDao) Ctx(ctx context.Context, uid int) *gdb.Model {
return dao.DB().Model(dao.setTable(uid)).Safe().Ctx(ctx)
}

// 改造后添加分表,按uid分表,作为传参
// Transaction wraps the transaction logic using function f.
// It rollbacks the transaction and returns the error from function f if it returns non-nil error.
// It commits the transaction and returns nil if function f returns nil.
//
// Note that, you should not Commit or Rollback the transaction in function f
// as it is automatically handled by this function.
func (dao *GameBestDao) Transaction(ctx context.Context, uid int, f func(ctx context.Context, tx gdb.TX) error) (err error) {
return dao.Ctx(ctx, uid).Transaction(ctx, f)
}

---------------------------------------------------------------我是分隔符------------------------------------------------------------------------------

----------------------------------------------------------------我是分隔符-----------------------------------------------------------------------------

./internal/model/do/game_best.go

package do

import (
"fmt"
"reflect"

"[github.com/gogf/gf/v2/frame/g](http://github.com/gogf/gf/v2/frame/g)"

)

// GameBest is the golang structure of table game_best for DAO operations like Where/Data.
type GameBestBase struct {
Uid interface{} // 玩家id
Money interface{} // 游戏币
Diamond interface{} // 钻石
Score interface{} // 积分
Exp interface{} // 经验
Coin interface{} // 现金币
Gcoin interface{} // 黄金币
}
type GameBest0 struct {
g.Meta orm:"table:game_best_0, do:true"
GameBestBase
}
type GameBest1 struct {
g.Meta orm:"table:game_best_1, do:true"
GameBestBase
}
type GameBest2 struct {
g.Meta orm:"table:game_best_2, do:true"
GameBestBase
}
type GameBest3 struct {
g.Meta orm:"table:game_best_3, do:true"
GameBestBase
}
type GameBest4 struct {
g.Meta orm:"table:game_best_4, do:true"
GameBestBase
}
type GameBest5 struct {
g.Meta orm:"table:game_best_5, do:true"
GameBestBase
}
type GameBest6 struct {
g.Meta orm:"table:game_best_6, do:true"
GameBestBase
}
type GameBest7 struct {
g.Meta orm:"table:game_best_7, do:true"
GameBestBase
}
type GameBest8 struct {
g.Meta orm:"table:game_best_8, do:true"
GameBestBase
}
type GameBest9 struct {
g.Meta orm:"table:game_best_9, do:true"
GameBestBase
}

// 创建一个map来存储不同类型的GameBestX结构体实例
var GameBestMap = map[string]interface{}{
"GameBest0": &GameBest0{},
"GameBest1": &GameBest1{},
"GameBest2": &GameBest2{},
"GameBest3": &GameBest3{},
"GameBest4": &GameBest4{},
"GameBest5": &GameBest5{},
"GameBest6": &GameBest6{},
"GameBest7": &GameBest7{},
"GameBest8": &GameBest8{},
"GameBest9": &GameBest9{},
}

// 创建和设置用户信息的函数
func CreateAndSetGameBest(uid int, in GameBestBase) (any, error) {
// 根据uid的值计算对应的结构体类型
GameBestType := fmt.Sprintf("GameBest%d", uid%10)
// 从map中获取对应的结构体实例
if GameBest, ok := GameBestMap[GameBestType]; ok {
// 使用反射设置结构体字段的值
val := reflect.ValueOf(GameBest).Elem()
SetGameBestField(val, "Uid", in.Uid)
SetGameBestField(val, "Money", in.Money)
SetGameBestField(val, "Diamond", in.Diamond)
SetGameBestField(val, "Score", in.Score)
SetGameBestField(val, "Exp", in.Exp)
SetGameBestField(val, "Coin", in.Coin)
SetGameBestField(val, "Gcoin", in.Gcoin)
return GameBest, nil
}
return nil, fmt.Errorf("unsupported user info type: %s", GameBestType)
}

// 使用反射设置结构体字段的值的辅助函数
func SetGameBestField(val reflect.Value, fieldName string, value interface{}) error {
field := val.FieldByName(fieldName)
if field.IsValid() && field.CanSet() {
field.Set(reflect.ValueOf(value))
}
return nil
}

------------------------------------我是分隔符-------------------------------------------------

------------------------------------我是分隔符-------------------------------------------------

使用dao对分表操作

// 生成玩家信息表
func CreateGameUserInfo(ctx context.Context, in model.GameLoginInput, uid int) (err error) {
var userinfo any
if userinfo, err = do.CreateAndSetUserInfo(uid, do.UserInfoBase{
Uid: uid,
Cid: in.Cid,
Lid: in.Lid,
Status: 1,
Nick: "Guest",
Sex: 0,
Icon: "",
UpdateTime: gtime.Timestamp(),
CreateTime: gtime.Timestamp(),
}); err != nil {
return err
}

dao.UserInfo.Transaction(ctx, uid, func(ctx context.Context, tx gdb.TX) (err error) {
    _, err = dao.UserInfo.Ctx(ctx, uid).Data(userinfo).Insert()
    return err
})
return err

}

2、根据年月周日规则生成表,比如 年表 order_sum_2024,月表order_202404,周表order_202434,日表order_20240425,这些表的规则就是数字部分固定长度,无法确定规则(周与月有相同数字),所以将这些数字作为参数传入,并且需要定时生成新表及修改文件,如果能加入gf gen dao 参数生成规则最好了,可以定时刷新

余数的也可以改成这个规则,传入的参数在logic判断可能更简单,其他非数字的有规律的分表,同理可操作

以下为例子

./internal/dao/internal/game_best.go

package internal

import (
"context"
"strconv"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/text/gstr"
)

。。。。

// NewGameBestDao creates and returns a new DAO object for table data access.
func NewGameBestDao() *GameBestDao {
return &GameBestDao{
group: "gamebest",
table: "order_",//除去末端数字余下部分
columns: gameBestColumns,
}
}

。。。。。。

// 处理分表,恢复实际表名
func (dao *GameBestDao) setTable(uid int) string {
var (
str = strconv.Itoa(uid)
array = []string{dao.table, str}
result = gstr.Join(array, ``)
)
return result
}

// 改造后添加分表,按uid分表,作为传参
// Ctx creates and returns the Model for current DAO, It automatically sets the context for current operation.
func (dao *GameBestDao) Ctx(ctx context.Context, uid int) *gdb.Model {
return dao.DB().Model(dao.setTable(uid)).Safe().Ctx(ctx)
}

// 改造后添加分表,按uid分表,作为传参
// Transaction wraps the transaction logic using function f.
// It rollbacks the transaction and returns the error from function f if it returns non-nil error.
// It commits the transaction and returns nil if function f returns nil.
//
// Note that, you should not Commit or Rollback the transaction in function f
// as it is automatically handled by this function.
func (dao *GameBestDao) Transaction(ctx context.Context, uid int, f func(ctx context.Context, tx gdb.TX) error) (err error) {
return dao.Ctx(ctx, uid).Transaction(ctx, f)
}

./internal/model/do/game_best.go

与上面文件类似即可

Additional

No response

@Issues-translate-bot Issues-translate-bot changed the title 关于数据库分表如何gf gen dao后文件的处理小建议,已测可行 Suggestions on how to process files after gf gen dao in database tables, it has been tested and feasible Apr 26, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant