package sql_mapping import ( "errors" "github.com/iancoleman/strcase" "reflect" "strings" ) const ( sqlMappingTagPartSeparator = ";" sqlMappingTagPartKeyValueSeparator = ":" ) const ( sqlMappingTagKey = "sqlmapping" sqlMappingIgnore = "-" sqlMappingColumn = "column" sqlMappingKey = "key" sqlMappingNotUpdate = "notUpdate" sqlMappingUpdateClear = "updateClear" sqlMappingNotQuery = "notQuery" sqlMappingQueryConditionCallback = "queryConditionCallback" ) type SqlMapping struct { ColumnMap map[string]SqlColumn } func ParseSqlMapping(e any) (*SqlMapping, error) { if e == nil { return nil, errors.New("没有传递实体") } entityType := reflect.TypeOf(e) if entityType.Kind() == reflect.Ptr { entityType = entityType.Elem() } if entityType.Kind() != reflect.Struct { return nil, errors.New("传递的不是实体结构") } sqlMapping := new(SqlMapping) sqlMapping.ColumnMap = make(map[string]SqlColumn) fieldNum := entityType.NumField() for i := 0; i < fieldNum; i++ { sqlColumn, err := parseSqlColumn(entityType.Field(i)) if err != nil { return nil, err } if sqlColumn == nil { continue } sqlMapping.ColumnMap[sqlColumn.Name] = *sqlColumn } return sqlMapping, nil } type SqlColumn struct { Name string IsKey bool CanUpdate bool CanUpdateClear bool CanQuery bool NeedQueryConditionCallback bool } func parseSqlColumn(field reflect.StructField) (*SqlColumn, error) { sqlColumn := &SqlColumn{ Name: strcase.ToSnake(field.Name), IsKey: false, CanUpdate: true, CanUpdateClear: false, CanQuery: true, NeedQueryConditionCallback: false, } sqlMappingTag, ok := field.Tag.Lookup(sqlMappingTagKey) if !ok { return sqlColumn, nil } if sqlMappingTag == sqlMappingIgnore { return nil, nil } sqlMappingParts := strings.Split(sqlMappingTag, sqlMappingTagPartSeparator) if sqlMappingParts != nil || len(sqlMappingParts) != 0 { for _, sqlMappingPart := range sqlMappingParts { sqlPartKeyValue := strings.Split(strings.TrimSpace(sqlMappingPart), sqlMappingTagPartKeyValueSeparator) switch sqlPartKeyValue[0] { case sqlMappingColumn: sqlColumn.Name = strings.TrimSpace(sqlPartKeyValue[1]) case sqlMappingKey: sqlColumn.IsKey = true sqlColumn.CanUpdate = false case sqlMappingNotUpdate: sqlColumn.CanUpdate = false case sqlMappingUpdateClear: sqlColumn.CanUpdateClear = true case sqlMappingNotQuery: sqlColumn.CanQuery = false case sqlMappingQueryConditionCallback: sqlColumn.NeedQueryConditionCallback = true default: continue } } } return sqlColumn, nil }