golang反射获取结构体的值和修改值
功能:根据id和反射技术封装 创建和更新人的查询
- 一、代码
- 二、演示
一、代码
package coryCommonimport ("context""errors""github.com/gogf/gf/v2/container/gvar""github.com/tiger1103/gfast/v3/internal/app/system/dao""reflect"
)func New() *coryCom {return &coryCom{}
}type coryCom struct{}// CreateByOrUpdateBy 专门用来反射结构体中的创建人和更新人,然后返回回去,避免重复造轮子去写重复代码
/**
*使用实例代码* by := coryCommon.New().CreateByOrUpdateBy(ctx, res)* infoRes := by.(model.BusCompanyInfoRes)* res = &infoRes**其中 updateByFieldVal.Set(reflect.ValueOf(updateByValue.Interface().(*gvar.Var).String())) 必须类型一致
*/
func (s *coryCom) CreateByOrUpdateBy(ctx context.Context, data interface{}) (dataRes interface{}) {// 使用反射获取 data 的值和类型信息val := reflect.ValueOf(data)typ := reflect.TypeOf(data)// 判断 data 是否为指针类型,并获取实际值if val.Kind() == reflect.Ptr {val = val.Elem()typ = typ.Elem()}// 获取 createBy 字段在结构体中的索引createByField, ok := typ.FieldByName("CreateBy")if !ok {// 如果结构体中不存在 createBy 字段,则直接返回原始值return data}updateByField, ok := typ.FieldByName("UpdateBy")if !ok {// 如果结构体中不存在 createBy 字段,则直接返回原始值return data}// 判断 createBy 字段的类型是否为 stringif createByField.Type.Kind() != reflect.String {// 如果 createBy 字段的类型不是 string,请根据需要进行相应的处理或返回错误// 此处假设 createBy 必须为 string 类型,如果不是则返回错误return errors.New("createBy字段类型不匹配")}// 判断 updateBy 字段的类型是否为 stringif updateByField.Type.Kind() != reflect.String {// 如果 createBy 字段的类型不是 string,请根据需要进行相应的处理或返回错误// 此处假设 createBy 必须为 string 类型,如果不是则返回错误return errors.New("updateBy字段类型不匹配")}// 获取原始的 createBy 字段的值并获取创建人createId := val.FieldByIndex(createByField.Index).String()value, err := dao.SysUser.Ctx(ctx).Fields("user_name").Where("id", createId).Value()if err != nil {return errors.New("系统异常,请联系管理员!")}// 设置 createBy 字段的值为指定参数createByValue := reflect.ValueOf(value)createByFieldVal := val.FieldByIndex(createByField.Index)createByFieldVal.Set(reflect.ValueOf(createByValue.Interface().(*gvar.Var).String()))// 获取原始的 createBy 字段的值并获取创建人updateId := val.FieldByIndex(updateByField.Index).String()value2, err := dao.SysUser.Ctx(ctx).Fields("user_name").Where("id", updateId).Value()if err != nil {return errors.New("系统异常,请联系管理员!")}// 设置 createBy 字段的值为指定参数updateByValue := reflect.ValueOf(value2)updateByFieldVal := val.FieldByIndex(updateByField.Index)updateByFieldVal.Set(reflect.ValueOf(updateByValue.Interface().(*gvar.Var).String()))// 返回修改后的结构体return val.Interface()
}
二、演示
封装好就可以直接在service层使用了【自己手动复制粘贴】
或者嫌麻烦就放到【代码生成器】中,这样就不用每次都去写这个查询了
by := coryCommon.New().CreateByOrUpdateBy(ctx, res)
infoRes := by.(model.BusEquipmentEquipmentUnpackingInfoRes)
res = &infoRes