添加 DataStructStrict 方法并实现严格模式解析

- 在 orm.go 和 orm_interface.go 中添加 DataStructStrict 方法,支持基于 tag 的严格解析
- 在 structEngineNew.go 中添加 StructToMapStrict 和 StructToMapStrictSlices 函数,仅解析带有指定标签的字段
This commit is contained in:
火线兔
2026-04-09 12:09:28 +08:00
parent d721356c88
commit a6ac82136c
3 changed files with 91 additions and 26 deletions
+6
View File
@@ -137,6 +137,12 @@ func (dba *Orm) DataStruct(data interface{}) IOrm {
return dba
}
// DataStructStrict : 这是在DataStruct基础上加入的基于tag判断的输入项,如果没有对应标签例如默认的gorose标签则不会解析
func (dba *Orm) DataStructStrict(data interface{}) IOrm {
dba.data = StructToMapStrictSlices(data)
return dba
}
// Group : select group by
func (dba *Orm) Group(group string) IOrm {
dba.group = group
+1
View File
@@ -19,6 +19,7 @@ type IOrm interface {
Distinct() IOrm
Data(data interface{}) IOrm
DataStruct(data interface{}) IOrm
DataStructStrict(data interface{}) IOrm
// groupBy, orderBy, having
Group(group string) IOrm
GroupBy(group string) IOrm
+84 -26
View File
@@ -5,8 +5,7 @@ import (
)
// ========================
// 版本1:返回 []map[string]interface{}
// 支持:struct/*struct/[]struct/[]*struct
// 【原有版本1】切片版
// ========================
func StructToMapSlices(data interface{}) []map[string]interface{} {
if data == nil {
@@ -14,13 +13,11 @@ func StructToMapSlices(data interface{}) []map[string]interface{} {
}
v := reflect.ValueOf(data)
return autoParse(v)
return autoParse(v, parseStructWithDefault)
}
// ========================
// 版本2:返回 map[string]interface{}
// 支持:struct/*struct
// 就是原版
// 【原有版本2】单个结构体
// ========================
func StructToMapV2(data interface{}) map[string]interface{} {
if data == nil {
@@ -29,7 +26,6 @@ func StructToMapV2(data interface{}) map[string]interface{} {
v := reflect.ValueOf(data)
// 解指针
for v.Kind() == reflect.Ptr {
if v.IsNil() {
return nil
@@ -41,11 +37,49 @@ func StructToMapV2(data interface{}) map[string]interface{} {
return nil
}
return parseStruct(v)
return parseStructWithDefault(v)
}
// 自动解析
func autoParse(v reflect.Value) []map[string]interface{} {
// ========================
// 【新增:严格模式 - 只有带tag才解析,无tag跳过】
// ========================
func StructToMapStrict(data interface{}) map[string]interface{} {
if data == nil {
return nil
}
v := reflect.ValueOf(data)
for v.Kind() == reflect.Ptr {
if v.IsNil() {
return nil
}
v = v.Elem()
}
if v.Kind() != reflect.Struct {
return nil
}
return parseStructStrict(v)
}
// ========================
// 【新增:严格模式切片版】
// ========================
func StructToMapStrictSlices(data interface{}) []map[string]interface{} {
if data == nil {
return nil
}
v := reflect.ValueOf(data)
return autoParse(v, parseStructStrict)
}
// ------------------------------
// 内部通用解析
// ------------------------------
func autoParse(v reflect.Value, parseFunc func(val reflect.Value) map[string]interface{}) []map[string]interface{} {
for v.Kind() == reflect.Ptr {
if v.IsNil() {
return nil
@@ -57,25 +91,29 @@ func autoParse(v reflect.Value) []map[string]interface{} {
switch v.Kind() {
case reflect.Struct:
res = append(res, parseStruct(v))
res = append(res, parseFunc(v))
case reflect.Slice, reflect.Array:
// 🔥 这里修复了:val.Len() → v.Len()
for i := 0; i < v.Len(); i++ {
item := v.Index(i)
for item.Kind() == reflect.Ptr {
item = item.Elem()
}
if item.Kind() == reflect.Struct {
res = append(res, parseStruct(item))
res = append(res, parseFunc(item))
}
}
default:
}
return res
}
// 解析结构体核心方法
func parseStruct(val reflect.Value) map[string]interface{} {
// ------------------------------
// 普通模式:无tag用字段名
// ------------------------------
func parseStructWithDefault(val reflect.Value) map[string]interface{} {
m := make(map[string]interface{})
typ := val.Type()
@@ -83,32 +121,52 @@ func parseStruct(val reflect.Value) map[string]interface{} {
field := typ.Field(i)
fv := val.Field(i)
// 跳过私有字段
if field.PkgPath != "" {
continue
}
// 跳过嵌套结构体
if fv.Kind() == reflect.Struct {
continue
}
// 读取 gorose 标签
tag := field.Tag.Get(TAGNAME)
// 忽略标记
if tag == "ignore" {
continue
}
// ======================
// ✅ 关键:无标签 → 使用结构体原生字段名
// ======================
if tag == "" {
tag = field.Name // 这里就是自动使用原生名字
tag = field.Name
}
m[tag] = fv.Interface()
}
return m
}
// ------------------------------
// 严格模式:无tag 直接跳过不解析
// ------------------------------
func parseStructStrict(val reflect.Value) map[string]interface{} {
m := make(map[string]interface{})
typ := val.Type()
for i := 0; i < val.NumField(); i++ {
field := typ.Field(i)
fv := val.Field(i)
if field.PkgPath != "" {
continue
}
if fv.Kind() == reflect.Struct {
continue
}
tag := field.Tag.Get(TAGNAME)
// 🔥 无tag 或 ignore → 跳过
if tag == "" || tag == "ignore" {
continue
}
// 保留所有值:0 / "" / false 都不会丢
m[tag] = fv.Interface()
}