model 使用文档
大约 8 分钟
前言
jzero 支持通过 desc/sql
文件夹下的 sql ddl 文件和远程数据源生成数据库代码到 internal/model
下.
为了在使用上更加方便, jzero 自动生成了 internal/model/model.go
文件, 用于注册所有生成的数据库代码.
当前支持 mysql 和 postgres 两种数据库类型, 其中:
- mysql: 同时支持 sql 文件和远程数据源两种方式生成代码
- postgres: 仅支持远程数据源生成代码
特性
- 支持多数据源生成代码
- 支持 redis/sync_map 缓存
- 动态适配多数据库类型, 仅修改配置文件指定数据库 driver 即可动态切换不同的数据库, 无需修改任何代码
基于本地 sql ddl 文件生成代码
desc/sql
├── casbin_rule.sql
├── manage_email.sql
├── manage_menu.sql
├── manage_role.sql
├── manage_role_menu.sql
└── manage_user.sql
└── manage_user_role.sql
gen:
# mysql or postgres, 默认为 mysql
model-driver: mysql
# 是否生成带缓存的数据库代码
model-cache: true
# 缓存表, 默认为 *(所有)
model-cache-table:
- manage_user
# schema
model-schema: jzeroadmin
# Ignore columns while creating or updating rows, 默认为 create_at,created_at,create_time,update_at,updated_at,update_time
model-ignore-columns: ["create_time", "update_time"]
生成的 internal/model/model.go
如下:
// Code generated by jzero. DO NOT EDIT.
package model
import (
"github.com/eddieowens/opts"
"github.com/jzero-io/jzero-admin/server/internal/model/casbin_rule"
"github.com/jzero-io/jzero-admin/server/internal/model/manage_email"
"github.com/jzero-io/jzero-admin/server/internal/model/manage_menu"
"github.com/jzero-io/jzero-admin/server/internal/model/manage_role"
"github.com/jzero-io/jzero-admin/server/internal/model/manage_role_menu"
"github.com/jzero-io/jzero-admin/server/internal/model/manage_user"
"github.com/jzero-io/jzero-admin/server/internal/model/manage_user_role"
"github.com/jzero-io/jzero/core/stores/modelx"
"github.com/zeromicro/go-zero/core/stores/sqlx"
)
type Model struct {
CasbinRule casbin_rule.CasbinRuleModel
ManageEmail manage_email.ManageEmailModel
ManageMenu manage_menu.ManageMenuModel
ManageRole manage_role.ManageRoleModel
ManageRoleMenu manage_role_menu.ManageRoleMenuModel
ManageUser manage_user.ManageUserModel
ManageUserRole manage_user_role.ManageUserRoleModel
}
func NewModel(conn sqlx.SqlConn, op ...opts.Opt[modelx.ModelOpts]) Model {
return Model{
CasbinRule: casbin_rule.NewCasbinRuleModel(conn, op...),
ManageEmail: manage_email.NewManageEmailModel(conn, op...),
ManageMenu: manage_menu.NewManageMenuModel(conn, op...),
ManageRole: manage_role.NewManageRoleModel(conn, op...),
ManageRoleMenu: manage_role_menu.NewManageRoleMenuModel(conn, op...),
ManageUser: manage_user.NewManageUserModel(conn, op...),
ManageUserRole: manage_user_role.NewManageUserRoleModel(conn, op...),
}
}
jzero 支持多数据源, 通过在 sql 文件中指定 schema 即可
如新增 jzeroadmin_log.operate_log.sql
表
desc/sql
├── casbin_rule.sql
├── manage_email.sql
├── manage_menu.sql
├── manage_role.sql
├── manage_role_menu.sql
└── manage_user.sql
└── manage_user_role.sql
└── jzeroadmin_log.operate_log.sql
生成的 internal/model/model.go
如下:
// Code generated by jzero. DO NOT EDIT.
package model
import (
"github.com/eddieowens/opts"
"github.com/jzero-io/jzero-admin/server/internal/model/casbin_rule"
"github.com/jzero-io/jzero-admin/server/internal/model/manage_email"
"github.com/jzero-io/jzero-admin/server/internal/model/manage_menu"
"github.com/jzero-io/jzero-admin/server/internal/model/manage_role"
"github.com/jzero-io/jzero-admin/server/internal/model/manage_role_menu"
"github.com/jzero-io/jzero-admin/server/internal/model/manage_user"
"github.com/jzero-io/jzero-admin/server/internal/model/manage_user_role"
"github.com/jzero-io/jzero-admin/server/internal/model/jzeroadmin_log/operate_log"
"github.com/jzero-io/jzero/core/stores/modelx"
"github.com/zeromicro/go-zero/core/stores/sqlx"
)
type Model struct {
CasbinRule casbin_rule.CasbinRuleModel
ManageEmail manage_email.ManageEmailModel
ManageMenu manage_menu.ManageMenuModel
ManageRole manage_role.ManageRoleModel
ManageRoleMenu manage_role_menu.ManageRoleMenuModel
ManageUser manage_user.ManageUserModel
ManageUserRole manage_user_role.ManageUserRoleModel
}
type JzeroadminLogModel struct {
OperateLog jzeroadmin_log.operate_log.OperateLogModel
}
func NewModel(conn sqlx.SqlConn, op ...opts.Opt[modelx.ModelOpts]) Model {
return Model{
CasbinRule: casbin_rule.NewCasbinRuleModel(conn, op...),
ManageEmail: manage_email.NewManageEmailModel(conn, op...),
ManageMenu: manage_menu.NewManageMenuModel(conn, op...),
ManageRole: manage_role.NewManageRoleModel(conn, op...),
ManageRoleMenu: manage_role_menu.NewManageRoleMenuModel(conn, op...),
ManageUser: manage_user.NewManageUserModel(conn, op...),
ManageUserRole: manage_user_role.NewManageUserRoleModel(conn, op...),
}
}
func NewJzeroadminLogModel(conn sqlx.SqlConn, op ...opts.Opt[modelx.ModelOpts]) JzeroadminLogModel {
return JzeroadminLogModel{
OperateLog: operate_log.NewOperateLogModel(conn, op...),
}
}
基于远程数据源地址生成代码
mysql
gen:
model-driver: mysql
# 是否生成带缓存的数据库代码
model-cache: true
# 缓存表, 默认为 *(所有)
model-cache-table:
- manage_user
# 是否使用远程 mysql 数据源生成代码
model-datasource: true
# mysql 数据源配置
model-datasource-url: "root:123456@tcp(127.0.0.1:3306)/jzeroadmin"
# Ignore columns while creating or updating rows, 默认为 create_at,created_at,create_time,update_at,updated_at,update_time
model-ignore-columns: ["create_time", "update_time"]
# 使用哪些 table, 默认为 *(所有)
model-datasource-table:
- casbin_rule
- manage_email
- manage_menu
- manage_role
- manage_role_menu
- manage_user
- manage_user_role
生成的 internal/model/model.go
与 基于本地 sql ddl 文件
生成的代码一致
jzero 支持多数据源, 通过在 model-datasource-table 中指定 schema 即可
如新增 jzeroadmin_log.operate_log
表
gen:
model-driver: mysql
# 是否生成带缓存的数据库代码
model-cache: true
# 缓存表, 默认为 *(所有)
model-cache-table:
- manage_user
# 是否使用远程 mysql 数据源生成代码
model-datasource: true
# mysql 数据源配置
model-datasource-url:
- "root:123456@tcp(127.0.0.1:3306)/jzeroadmin"
- "root:123456@tcp(127.0.0.1:3306)/jzeroadmin_log"
# Ignore columns while creating or updating rows, 默认为 create_at,created_at,create_time,update_at,updated_at,update_time
model-ignore-columns: ["create_time", "update_time"]
# 使用哪些 table, 默认为 *(所有)
model-datasource-table:
- casbin_rule
- manage_email
- manage_menu
- manage_role
- manage_role_menu
- manage_user
- manage_user_role
- jzeroadmin_log.operate_log
生成的 internal/model/model.go
与 基于本地 sql ddl 文件
生成的代码一致
postgres
gen:
model-driver: postgres
# 是否生成带缓存的数据库代码
model-cache: true
# 缓存表, 默认为 *(所有)
model-cache-table:
- manage_user
# 是否使用远程 postgres 数据源生成代码
model-datasource: true
# postgres 数据源配置
model-datasource-url: "postgres://root:123456@127.0.0.1:5432/jzeroadmin?sslmode=disable"
# Ignore columns while creating or updating rows, 默认为 create_at,created_at,create_time,update_at,updated_at,update_time
model-ignore-columns: ["create_time", "update_time"]
# 使用哪些 table, 默认为 *(所有)
model-datasource-table:
- casbin_rule
- manage_email
- manage_menu
- manage_role
- manage_role_menu
- manage_user
- manage_user_role
生成的 internal/model/model.go
与 mysql driver 一致
jzero 支持多数据源, 通过在 model-datasource-table 中指定 schema 即可
如新增 jzeroadmin_log.operate_log
表
gen:
model-driver: postgres
# 是否生成带缓存的数据库代码
model-cache: true
# 缓存表, 默认为 *(所有)
model-cache-table:
- manage_user
# 是否使用远程 postgres 数据源生成代码
model-datasource: true
# postgres 数据源配置
model-datasource-url:
- "postgres://root:123456@127.0.0.1:5432/jzeroadmin?sslmode=disable"
- "postgres://root:123456@127.0.0.1:5432/jzeroadmin_log?sslmode=disable"
# Ignore columns while creating or updating rows, 默认为 create_at,created_at,create_time,update_at,updated_at,update_time
model-ignore-columns: ["create_time", "update_time"]
# 使用哪些 table, 默认为 *(所有)
model-datasource-table:
- casbin_rule
- manage_email
- manage_menu
- manage_role
- manage_role_menu
- manage_user
- manage_user_role
- jzeroadmin_log.operate_log
生成的 internal/model/model.go
与 mysql driver 一致
默认生成如下方法
- Insert: 插入单条数据
- BulkInsert: 批量插入数据
- Update: 根据主键更新单条数据
- Delete: 根据主键删除单条数据
- FindOne: 根据主键查询单条数据
- FindByCondition: 条件查询
- FindSelectedColumnsByCondition: 条件查询(指定查询字段)
- FindOneByCondition: 条件查询单条数据
- CountByCondition: 条件查询总数
- PageByCondition: 条件分页查询
- UpdateFieldsByCondition: 条件更新指定字段
- DeleteByCondition: 条件删除
package manage_menu
type manageMenuModel interface {
Insert(ctx context.Context, session sqlx.Session, data *ManageMenu) (sql.Result, error)
FindOne(ctx context.Context, session sqlx.Session, id uint64) (*ManageMenu, error)
Update(ctx context.Context, session sqlx.Session, data *ManageMenu) error
Delete(ctx context.Context, session sqlx.Session, id uint64) error
// custom interface generated by jzero
BulkInsert(ctx context.Context, session sqlx.Session, datas []*ManageMenu) error
FindByCondition(ctx context.Context, session sqlx.Session, conds ...condition.Condition) ([]*ManageMenu, error)
FindSelectedColumnsByCondition(ctx context.Context, session sqlx.Session, columns []string, conds ...condition.Condition) ([]*ManageMenu, error)
FindOneByCondition(ctx context.Context, session sqlx.Session, conds ...condition.Condition) (*ManageMenu, error)
CountByCondition(ctx context.Context, session sqlx.Session, conds ...condition.Condition) (int64, error)
PageByCondition(ctx context.Context, session sqlx.Session, conds ...condition.Condition) ([]*ManageMenu, int64, error)
UpdateFieldsByCondition(ctx context.Context, session sqlx.Session, field map[string]any, conds ...condition.Condition) error
DeleteByCondition(ctx context.Context, session sqlx.Session, conds ...condition.Condition) error
}
数据库最佳实践
初始化数据库连接
etc/etc.yaml
rest:
name: jzero-admin-api
host: 0.0.0.0
port: 8001
timeout: 20000
databaseType: "mysql"
databaseUrl: "root:123456@tcp(127.0.0.1:3306)/jzeroadmin?charset=utf8mb4&parseTime=True&loc=Local"
redis:
host: "127.0.0.1:6379"
type: "node"
cache:
type: "redis"
internal/config/config.go
package config
import (
"github.com/jzero-io/jzero/core/stores/modelx"
"github.com/zeromicro/go-zero/core/stores/redis"
"github.com/zeromicro/go-zero/rest"
)
type Config struct {
// rest 服务配置
Rest RestConf
// 数据库配置
modelx.ModelConf
// 缓存配置
// 缓存类型
CacheType string `json:",default=local"`
// redis 配置
Redis redis.RedisConf `json:",optional"`
}
type RestConf struct {
rest.RestConf
}
internal/svc/service_context.go
package svc
import (
"net/http"
"time"
"github.com/jzero-io/jzero/core/stores/cache"
"github.com/jzero-io/jzero/core/stores/modelx"
"github.com/pkg/errors"
configurator "github.com/zeromicro/go-zero/core/configcenter"
zerocache "github.com/zeromicro/go-zero/core/stores/cache"
"github.com/zeromicro/go-zero/core/stores/redis"
"github.com/zeromicro/go-zero/core/stores/sqlc"
"github.com/zeromicro/go-zero/core/stores/sqlx"
"github.com/jzero-io/jzero-admin/server/internal/config"
"github.com/jzero-io/jzero-admin/server/internal/model"
)
type ServiceContext struct {
Config configurator.Configurator[config.Config]
SqlxConn sqlx.SqlConn
Model model.Model
Cache cache.Cache
}
func NewServiceContext(cc configurator.Configurator[config.Config], route2Code func(r *http.Request) string) *ServiceContext {
svcCtx := &ServiceContext{
Config: cc,
}
svcCtx.SetConfigListener()
svcCtx.SqlxConn = modelx.MustSqlConn(svcCtx.MustGetConfig().ModelConf)
if svcCtx.MustGetConfig().CacheType == "local" {
svcCtx.Cache = cache.NewSyncMap(errors.New("cache not found"))
} else {
// redis cache
rds := redis.MustNewRedis(svcCtx.MustGetConfig().Redis)
svcCtx.Cache = cache.NewRedisNode(rds, errors.New("cache not found"), zerocache.WithExpiry(time.Duration(5)*time.Second))
}
svcCtx.Model = model.NewModel(svcCtx.SqlxConn, modelx.WithCachedConn(sqlc.NewConnWithCache(svcCtx.SqlxConn, svcCtx.Cache)))
return svcCtx
}
业务逻辑使用生成的数据库代码
internal/logic/manage/user/add.go(插入数据)
package user
import (
"context"
"net/http"
"time"
"github.com/guregu/null/v5"
"github.com/jzero-io/jzero/core/stores/condition"
"github.com/zeromicro/go-zero/core/logx"
"github.com/jzero-io/jzero-admin/server/internal/model/manage_role"
"github.com/jzero-io/jzero-admin/server/internal/model/manage_user"
"github.com/jzero-io/jzero-admin/server/internal/model/manage_user_role"
"github.com/jzero-io/jzero-admin/server/internal/svc"
types "github.com/jzero-io/jzero-admin/server/internal/types/manage/user"
)
type Add struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
r *http.Request
}
func NewAdd(ctx context.Context, svcCtx *svc.ServiceContext, r *http.Request) *Add {
return &Add{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx, r: r,
}
}
func (l *Add) Add(req *types.AddRequest) (resp *types.AddResponse, err error) {
if _, err = l.svcCtx.Model.ManageUser.Insert(l.ctx, nil, &manage_user.ManageUser{
CreateTime: time.Now(),
UpdateTime: time.Now(),
Username: req.Username,
Password: req.Password,
Nickname: req.NickName,
Gender: req.UserGender,
Phone: null.StringFrom(req.UserPhone).NullString,
Status: req.Status,
Email: null.StringFrom(req.UserEmail).NullString,
}); err != nil {
return nil, err
}
user, err := l.svcCtx.Model.ManageUser.FindOneByUsername(l.ctx, nil, req.Username)
if err != nil {
return nil, err
}
var bulk []*manage_user_role.ManageUserRole
var roleIds []uint64
roles, err := l.svcCtx.Model.ManageRole.FindByCondition(l.ctx, nil, condition.Condition{
Field: manage_role.Code,
Operator: condition.In,
Value: req.UserRoles,
})
if err != nil {
return nil, err
}
for _, v := range roles {
roleIds = append(roleIds, v.Id)
}
for _, v := range roleIds {
bulk = append(bulk, &manage_user_role.ManageUserRole{
CreateTime: time.Now(),
UpdateTime: time.Now(),
UserId: int64(user.Id),
RoleId: int64(v),
})
}
err = l.svcCtx.Model.ManageUserRole.BulkInsert(l.ctx, nil, bulk)
return
}
internal/logic/manage/user/delete.go(删除数据)
package user
import (
"context"
"net/http"
"github.com/jzero-io/jzero/core/stores/condition"
"github.com/zeromicro/go-zero/core/logx"
"github.com/zeromicro/go-zero/core/stores/sqlx"
"github.com/jzero-io/jzero-admin/server/internal/model/manage_user"
"github.com/jzero-io/jzero-admin/server/internal/svc"
types "github.com/jzero-io/jzero-admin/server/internal/types/manage/user"
)
type Delete struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
r *http.Request
}
func NewDelete(ctx context.Context, svcCtx *svc.ServiceContext, r *http.Request) *Delete {
return &Delete{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx, r: r,
}
}
func (l *Delete) Delete(req *types.DeleteRequest) (resp *types.DeleteResponse, err error) {
if len(req.Ids) == 0 {
return nil, nil
}
err = l.svcCtx.SqlxConn.TransactCtx(l.ctx, func(ctx context.Context, session sqlx.Session) error {
if err = l.svcCtx.Model.ManageUser.DeleteByCondition(l.ctx, session, condition.Condition{
Field: manage_user.Id,
Operator: condition.In,
Value: req.Ids,
}); err != nil {
return err
}
if err = l.svcCtx.Model.ManageUserRole.DeleteByCondition(l.ctx, session, condition.NewChain().In("user_id", req.Ids).Build()...); err != nil {
return err
}
return nil
})
return
}
internal/logic/manage/user/edit.go(更新数据)
package user
import (
"context"
"net/http"
"time"
"github.com/guregu/null/v5"
"github.com/jzero-io/jzero/core/stores/condition"
"github.com/zeromicro/go-zero/core/logx"
"github.com/jzero-io/jzero-admin/server/internal/model/manage_role"
"github.com/jzero-io/jzero-admin/server/internal/model/manage_user_role"
"github.com/jzero-io/jzero-admin/server/internal/svc"
types "github.com/jzero-io/jzero-admin/server/internal/types/manage/user"
)
type Edit struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
r *http.Request
}
func NewEdit(ctx context.Context, svcCtx *svc.ServiceContext, r *http.Request) *Edit {
return &Edit{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx, r: r,
}
}
func (l *Edit) Edit(req *types.EditRequest) (resp *types.EditResponse, err error) {
user, err := l.svcCtx.Model.ManageUser.FindOne(l.ctx, nil, req.Id)
if err != nil {
return nil, err
}
user.Username = req.Username
user.Nickname = req.NickName
user.Email = null.StringFrom(req.UserEmail).NullString
user.Phone = null.StringFrom(req.UserPhone).NullString
user.Gender = req.UserGender
user.Status = req.Status
user.UpdateTime = time.Now()
if err = l.svcCtx.Model.ManageUser.Update(l.ctx, nil, user); err != nil {
return nil, err
}
// 更新 system_user_role 表
if err = l.svcCtx.Model.ManageUserRole.DeleteByCondition(l.ctx, nil, condition.Condition{
Field: manage_user_role.UserId,
Operator: condition.Equal,
Value: req.Id,
}); err != nil {
return nil, err
}
var bulk []*manage_user_role.ManageUserRole
var roleIds []uint64
roles, err := l.svcCtx.Model.ManageRole.FindByCondition(l.ctx, nil, condition.Condition{
Field: manage_role.Code,
Operator: condition.In,
Value: req.UserRoles,
})
if err != nil {
return nil, err
}
for _, v := range roles {
roleIds = append(roleIds, v.Id)
}
for _, v := range roleIds {
bulk = append(bulk, &manage_user_role.ManageUserRole{
CreateTime: time.Now(),
UpdateTime: time.Now(),
UserId: int64(user.Id),
RoleId: int64(v),
})
}
if err = l.svcCtx.Model.ManageUserRole.BulkInsert(l.ctx, nil, bulk); err != nil {
return nil, err
}
return
}
internal/logic/manage/user/list.go(获取列表)
package user
import (
"context"
"net/http"
"time"
"github.com/guregu/null/v5"
"github.com/jzero-io/jzero/core/stores/condition"
"github.com/zeromicro/go-zero/core/logx"
"github.com/zeromicro/go-zero/core/mr"
"github.com/jzero-io/jzero-admin/server/internal/model/manage_role"
"github.com/jzero-io/jzero-admin/server/internal/model/manage_user"
"github.com/jzero-io/jzero-admin/server/internal/model/manage_user_role"
"github.com/jzero-io/jzero-admin/server/internal/svc"
types "github.com/jzero-io/jzero-admin/server/internal/types/manage/user"
)
type List struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
r *http.Request
}
func NewList(ctx context.Context, svcCtx *svc.ServiceContext, r *http.Request) *List {
return &List{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx, r: r,
}
}
func (l *List) List(req *types.ListRequest) (resp *types.ListResponse, err error) {
users, total, err := l.svcCtx.Model.ManageUser.PageByCondition(l.ctx, nil, condition.Condition{
Operator: condition.Limit,
Value: req.Size,
}, condition.Condition{
Operator: condition.Offset,
Value: (req.Current - 1) * req.Size,
}, condition.Condition{
Skip: req.Username == "",
Field: manage_user.Username,
Operator: condition.Like,
Value: "%" + req.Username + "%",
}, condition.Condition{
Skip: req.UserGender == "",
Field: manage_user.Gender,
Operator: condition.Equal,
Value: req.UserGender,
}, condition.Condition{
Skip: req.NickName == "",
Field: manage_user.Nickname,
Operator: condition.Like,
Value: "%" + req.NickName + "%",
}, condition.Condition{
Skip: req.UserPhone == "",
Field: manage_user.Phone,
Operator: condition.Like,
Value: "%" + req.UserPhone + "%",
}, condition.Condition{
Skip: req.UserEmail == "",
Field: manage_user.Email,
Operator: condition.Like,
Value: "%" + req.UserEmail + "%",
}, condition.Condition{
Skip: req.Status == "",
Field: manage_user.Status,
Operator: condition.Equal,
Value: req.Status,
})
var records []types.ManageUser
for _, user := range users {
records = append(records, types.ManageUser{
Id: user.Id,
Username: user.Username,
UserGender: user.Gender,
NickName: user.Nickname,
UserPhone: null.NewString(user.Phone.String, user.Phone.Valid).ValueOrZero(),
UserEmail: null.NewString(user.Email.String, user.Email.Valid).ValueOrZero(),
Status: user.Status,
CreateTime: user.CreateTime.Format(time.DateTime),
UpdateTime: user.UpdateTime.Format(time.DateTime),
})
}
err = mr.MapReduceVoid(func(source chan<- int) {
for index := range records {
source <- index
}
}, func(item int, writer mr.Writer[types.ManageUser], cancel func(error)) {
userRoles, err := l.svcCtx.Model.ManageUserRole.FindByCondition(l.ctx, nil, condition.Condition{
Field: manage_user_role.UserId,
Operator: condition.Equal,
Value: records[item].Id,
})
if err != nil {
cancel(err)
return
}
var roleIds []int
for _, userRole := range userRoles {
roleIds = append(roleIds, int(userRole.RoleId))
}
if len(roleIds) == 0 {
return
}
roles, err := l.svcCtx.Model.ManageRole.FindByCondition(l.ctx, nil, condition.Condition{
Field: manage_role.Id,
Operator: condition.In,
Value: roleIds,
})
if err != nil {
cancel(err)
return
}
var roleCodes []string
for _, role := range roles {
roleCodes = append(roleCodes, role.Code)
}
records[item].UserRoles = roleCodes
}, func(pipe <-chan types.ManageUser, cancel func(error)) {})
resp = &types.ListResponse{
Records: records,
PageResponse: types.PageResponse{
Current: req.Current,
Size: req.Size,
Total: total,
},
}
return
}