曹旭辉 发表于 2024-10-19 02:16:42

go gorm StructField动态天生结构体查询多条表记录 开辟者神器、DB通用微服

water/goweb
type PagedbRequest struct {
    page.PageRequest

    //表名
    TableName string `json:"table_name"`
    //字段列表,分隔
    FieldsName string `json:"fields_name"`
    //返回日期转为int64
    TimeToIntbool `json:"time_to_int"`
    Camel2Case bool `json:"-"`

    SubTable*SubTableDto `json:"sub_table,omitempty"`
    JoinTable *SubTableDto `json:"join_table,omitempty"`
}
type PageRequest struct {
    basedto.BaseEntity `json:"-"`
    RequestId          string `json:"request_id"`
    //每页记录数
    PageSize int `json:"page_size"`
    //当前页码
    PageCurrent int `json:"current"`
    //排序字段数组
    OrderBys []*dto.OrderByDto `json:"order_by"`
    //查询字段条件
    Fields   []*dto.QueryField `json:"fields"`
    EsBoolType int               `json:"es_bool_type"`

    *baseconfig.DbClientDto `json:"-"`
} type PageResult struct {
    basedto.BaseEntity

    Code int    `json:"code"`
    Msgstring `json:"msg"`

    PageSize    int `json:"page_size,omitempty"`
    PageCurrent int `json:"current,omitempty"`

    Total         int             `json:"total,omitempty"`
    Data          any             `json:"data"`
   
}
测试用例 func Test013_GeneralScanTable(t *testing.T) {

    var dbRequest = Default().SetPageSize(3)

    dbRequest.TableName = "sys_dept"
    dbRequest.FieldsName = "dept_id,dept_name" //dbRequest.SetQueryAll(true)
    var result = dbRequest.GeneralScanTable()
    golog.Info(result)

} 2024-10-13 10:51:45.312 {
     "code": 200,
     "msg": "乐成",
     "page_size": 3,
     "current": 1,
     "total": 10,
     "data": [
          {
               "DeptId": 100,
               "DeptName": "若依科技"
          },
          {
               "DeptId": 101,
               "DeptName": "深圳总公司"
          },
          {
               "DeptId": 102,
               "DeptName": "长沙分公司"
          }
     ],
  
}

代码实现
package pagedb

import (
    "errors"
    "gitee.com/leijmdas/gobase/goconfig/common/base/basedto"
    "gitee.com/leijmdas/gobase/goconfig/common/base/baseutils"
    "gitee.com/leijmdas/gobase/goconfig/common/base/jsonutils"
    "gitee.com/leijmdas/gobase/goconfig/common/base/stringutils"
    "gitee.com/leijmdas/gobase/goconfig/common/gocontext"
    "gitee.com/leijmdas/gobase/goconfig/common/golog"
    "gitee.com/leijmdas/gobase/goconfig/common/ichubconfig"
    "gitee.com/leijmdas/goweb/common/meta/metadata"
    "gitee.com/leijmdas/goweb/common/meta/service"
    "gitee.com/leijmdas/goweb/commonpage/page"
    "github.com/huandu/go-clone"
    "github.com/jinzhu/gorm"
    "reflect"
    "time"

    "github.com/sirupsen/logrus"
    "strings"
) func (self *PagedbRequest) GeneralScanTable() *page.PageResult {
    var metadataFactroy = service.FindBeanMetadataFactroy() //(self.DbClientDto)
    var metadata = metadataFactroy.FindMetadata(self.TableName)
    if !metadata.TableExist {
       return page.ResultFailedPageResultErr(errors.New("table not exist"))
    }
    var dbentity = self.CreateDbTableStru(metadata)
    var records, err = self.ScanTable(dbentity.Addr().Interface())

    if err != nil {
       return page.ResultFailedPageResultErr(err)
    }

    var result = page.DefaultResult()
    result.PageCurrent = self.PageCurrent
    result.PageSize = self.PageSize
    result.Total, _ = self.CountTable(self.TableName)
    result.Data = records
    return result

} func (self *PagedbRequest) CreateDbTableStru(meta *metadata.MetadataTable) reflect.Value {
    // logrus.Info("CreateDbTableStru meta=", meta.ToPrettyString())
    var metaColService = service.NewMetadataFactroy()
    dbFields := []reflect.StructField{}

    for _, col := range meta.Columns {
       //logrus.Info("CreateDbTableStru col=", col.ToPrettyString())
       var colType = metaColService.FindGoType(col.DataType)
       var ColTyp8 = reflect.TypeOf(int8(0))

       var ct = func(colType string) *reflect.Type {
          var ColTyp = reflect.TypeOf(int8(0))
          switch colType {
          case "float64":
             ColTyp = reflect.TypeOf(float64(0))
          case "int64":
             ColTyp = reflect.TypeOf(int64(0))
          case "int32":
             ColTyp = reflect.TypeOf(int64(0))
          case "string":
             ColTyp = reflect.TypeOf("")
          case "bool":
             ColTyp = reflect.TypeOf(true)
          case "byte":
             ColTyp = reflect.TypeOf(byte(0))
          case "[]byte":
             ColTyp = reflect.TypeOf([]byte{})

          case "time.Time":
             ColTyp = reflect.TypeOf(time.Now())

          }
          return &ColTyp
       }(colType)
       if ColTyp8 != *ct {
          var colField = reflect.StructField{
             Name: stringutils.Case2Camel(col.ColumnName),
             Type: *ct,
          }
          if self.IfExistField(col.ColumnName) {
             //colField.Tag = reflect.StructTag(fmt.Sprintf("json:\"%s\"", col.ColumnName))

             dbFields = append(dbFields, colField)
          }
       }
    }

    dbtableType := reflect.StructOf(dbFields)
    dbentity := reflect.New(dbtableType).Elem()
    return dbentity
} func (self *PagedbRequest) IfExistField(field string) bool {
    if self.FieldsName == "" {
       return true
    }
    if strings.Contains(field, ",") {
       return false
    }
    var fields = strings.Split(self.FieldsName, ",")
    for _, v := range fields {
       if v == field {
          return true
       }
    }
    return false
} func (self *PagedbRequest) ScanTable(dbentity any) (any, error) {

    var records = []any{} //reflect.New(reflect.SliceOf(dbtableType)).Elem()

    var dbc = self.FindScanTable()
    var rows, err = dbc.Rows()
    if err != nil {
       golog.Error(err)
       return records, err
    }

    defer func() {
       rows.Close()
    }()
    for rows.Next() {
       dbentity = clone.Clone(dbentity) //    dbentity := reflect.New(dbtableType).Elem()
       if err := dbc.ScanRows(rows, dbentity); err != nil {
          golog.Error("should get no error, but got ", err)
          return records, err
       }
       records = append(records, dbentity)
    }

    return baseutils.ParseArray2Map(records)

}
func (self *PagedbRequest) FindScanTable() *gorm.DB {

    dbc := self.GetDB().Table(self.TableName)

    dbc = self.BuildWhere(dbc)
    dbc = self.Order(dbc)
    dbc = self.SetLimit(dbc)
    if self.FieldsName != "" {
       dbc = dbc.Select(strings.Split(self.FieldsName, ","))
    }
    return dbc

} func ParseArray2Map(stru []any) (any, error) {
    var bytes, err = gjson.Encode(stru)
    if err != nil {
       return nil, err
    }
    logrus.Info(1)
    return gjson.Decode(bytes)

}
func (self *PageRequest) CountTable(table string) (int, error) {
    dbc := self.GetDB().Table(table)
    dbc = self.BuildWhere(dbc).Offset(0).Limit(1)
    var count int
    if err := dbc.Count(&count).Error; err != nil {
       logrus.Error(err)
       return 0, err
    }

    logrus.Info("\ncount=", count)
    return count, nil

}
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: go gorm StructField动态天生结构体查询多条表记录 开辟者神器、DB通用微服