package sql import ( "git.sxidc.com/go-framework/baize/framework/core/infrastructure/logger" "git.sxidc.com/go-framework/baize/framework/core/tag/sql/sql_result" "git.sxidc.com/go-tools/utils/reflectutils" "git.sxidc.com/go-tools/utils/strutils" "github.com/pkg/errors" "reflect" "strings" "time" ) const ( resultTimeMicroFormat = "2006-01-02T15:04:05.000000+08:00" resultTimeMilliFormat = "2006-01-02T15:04:05.000+08:00" resultTimeSecFormat = "2006-01-02T15:04:05+08:00" ) // Result 查询结果 type Result map[string]any // ColumnValueTime 以time.Time类型获取列值 // 参数: // - columnName: 列名 // 返回值: // - time.Time类型的列值 func (result Result) ColumnValueTime(columnName string) time.Time { value, ok := result[columnName].(string) if !ok { value, ok := result[columnName].(time.Time) if !ok { logger.GetInstance().Error(errors.New("无法转换为时间类型")) return time.Time{} } return value } layout := resultTimeSecFormat parseValue := value timeZoneIndex := strings.LastIndex(value, "+08:") if timeZoneIndex != -1 { parseValue = parseValue[:timeZoneIndex] afterSecondIndex := strings.LastIndex(parseValue, ".") if afterSecondIndex != -1 { if len(value)-afterSecondIndex-1 == 6 { layout = resultTimeMicroFormat } else if len(value)-afterSecondIndex-1 == 3 { layout = resultTimeMilliFormat } } } t, err := time.ParseInLocation(layout, value, time.Local) if err != nil { return time.Time{} } return t } // ColumnValueBool 以bool类型获取列值 // 参数: // - columnName: 列名 // 返回值: // - bool类型的列值 func (result Result) ColumnValueBool(columnName string) bool { value, err := reflectutils.ToBool(result[columnName]) if err != nil { logger.GetInstance().Error(err) return false } return value } // ColumnValueString 以string类型获取列值 // 参数: // - columnName: 列名 // 返回值: // - string类型的列值 func (result Result) ColumnValueString(columnName string) string { value, err := reflectutils.ToString(result[columnName]) if err != nil { logger.GetInstance().Error(err) return "" } return value } // ColumnValueInt 以int类型获取列值 // 参数: // - columnName: 列名 // 返回值: // - int类型的列值 func (result Result) ColumnValueInt(columnName string) int { value, err := reflectutils.ToInt64(result[columnName]) if err != nil { logger.GetInstance().Error(err) return 0 } return int(value) } // ColumnValueInt8 以int8类型获取列值 // 参数: // - columnName: 列名 // 返回值: // - int8类型的列值 func (result Result) ColumnValueInt8(columnName string) int8 { value, err := reflectutils.ToInt64(result[columnName]) if err != nil { logger.GetInstance().Error(err) return 0 } return int8(value) } // ColumnValueInt16 以int16类型获取列值 // 参数: // - columnName: 列名 // 返回值: // - int16类型的列值 func (result Result) ColumnValueInt16(columnName string) int16 { value, err := reflectutils.ToInt64(result[columnName]) if err != nil { logger.GetInstance().Error(err) return 0 } return int16(value) } // ColumnValueInt32 以int32类型获取列值 // 参数: // - columnName: 列名 // 返回值: // - int32类型的列值 func (result Result) ColumnValueInt32(columnName string) int32 { value, err := reflectutils.ToInt64(result[columnName]) if err != nil { logger.GetInstance().Error(err) return 0 } return int32(value) } // ColumnValueInt64 以int64类型获取列值 // 参数: // - columnName: 列名 // 返回值: // - int64类型的列值 func (result Result) ColumnValueInt64(columnName string) int64 { value, err := reflectutils.ToInt64(result[columnName]) if err != nil { logger.GetInstance().Error(err) return 0 } return value } // ColumnValueUint 以uint类型获取列值 // 参数: // - columnName: 列名 // 返回值: // - uint类型的列值 func (result Result) ColumnValueUint(columnName string) uint { value, err := reflectutils.ToUint64(result[columnName]) if err != nil { logger.GetInstance().Error(err) return 0 } return uint(value) } // ColumnValueUint8 以uint8类型获取列值 // 参数: // - columnName: 列名 // 返回值: // - uint8类型的列值 func (result Result) ColumnValueUint8(columnName string) uint8 { value, err := reflectutils.ToUint64(result[columnName]) if err != nil { logger.GetInstance().Error(err) return 0 } return uint8(value) } // ColumnValueUint16 以uint16类型获取列值 // 参数: // - columnName: 列名 // 返回值: // - uint16类型的列值 func (result Result) ColumnValueUint16(columnName string) uint16 { value, err := reflectutils.ToUint64(result[columnName]) if err != nil { logger.GetInstance().Error(err) return 0 } return uint16(value) } // ColumnValueUint32 以uint32类型获取列值 // 参数: // - columnName: 列名 // 返回值: // - uint32类型的列值 func (result Result) ColumnValueUint32(columnName string) uint32 { value, err := reflectutils.ToUint64(result[columnName]) if err != nil { logger.GetInstance().Error(err) return 0 } return uint32(value) } // ColumnValueUint64 以uint64类型获取列值 // 参数: // - columnName: 列名 // 返回值: // - uint64类型的列值 func (result Result) ColumnValueUint64(columnName string) uint64 { value, err := reflectutils.ToUint64(result[columnName]) if err != nil { logger.GetInstance().Error(err) return 0 } return value } // ColumnValueFloat32 以float32类型获取列值 // 参数: // - columnName: 列名 // 返回值: // - float32类型的列值 func (result Result) ColumnValueFloat32(columnName string) float32 { value, err := reflectutils.ToFloat64(result[columnName]) if err != nil { logger.GetInstance().Error(err) return 0 } return float32(value) } // ColumnValueFloat64 以float64类型获取列值 // 参数: // - columnName: 列名 // 返回值: // - float64类型的列值 func (result Result) ColumnValueFloat64(columnName string) float64 { value, err := reflectutils.ToFloat64(result[columnName]) if err != nil { logger.GetInstance().Error(err) return 0 } return value } // ParseSqlResult 解析查询结果 // 参数: // - input: sql.Result或者[]sql.Result类型的查询结果 // - output: 接收查询结果的指针,如果是结构,需要使用sqlresult tag标注字段 // 返回值: // - 错误 func ParseSqlResult(input any, output any) error { return ParseSqlResultWithColumn(input, output, "") } // ParseSqlResultWithColumn 取查询结果列解析结果 // 参数: // - input: sql.Result或者[]sql.Result类型的查询结果 // - output: 接收查询结果的指针,如果是结构,需要使用sqlresult tag标注字段 // - columnName: 获取的列名 // 返回值: // - 错误 func ParseSqlResultWithColumn(input any, output any, columnName string) error { if input == nil { return nil } if output == nil { return nil } typeCheckErr := errors.New("可以接受的输出类型为指针或者slice的指针") outputType := reflect.TypeOf(output) if outputType.Kind() != reflect.Pointer { return typeCheckErr } outputElemType := reflectutils.PointerTypeElem(outputType) // 输出不是slice,直接用result赋值即可 if outputElemType.Kind() != reflect.Slice { result, ok := input.(Result) if !ok { return errors.New("输出不是slice,输入需要是sql.Result") } return parseSqlSingle(result, output, columnName) } // 输出是slice,需要遍历处理 results, ok := input.([]Result) if !ok { return errors.New("输出是slice,输入需要是[]sql.Result") } outputEntities := reflect.MakeSlice(outputElemType, 0, 0) for _, result := range results { var outputEntityValue reflect.Value // slice子类型判断 if outputElemType.Elem().Kind() == reflect.Pointer { outputEntityValue = reflect.New(outputElemType.Elem().Elem()) err := parseSqlSingle(result, outputEntityValue.Interface(), columnName) if err != nil { return err } } else { outputEntityValue = reflect.New(outputElemType.Elem()).Elem() err := parseSqlSingle(result, outputEntityValue.Addr().Interface(), columnName) if err != nil { return err } } outputEntities = reflect.Append(outputEntities, outputEntityValue) } outputElemValue := reflectutils.PointerValueElem(reflect.ValueOf(output)) outputElemValue.Set(outputEntities) return nil } func parseSqlSingle(result Result, output any, columnName string) error { outputValue := reflectutils.PointerValueElem(reflect.ValueOf(output)) outputKind := reflectutils.GroupValueKind(outputValue) var oneResultValue any if strutils.IsStringEmpty(columnName) { for _, value := range result { oneResultValue = value break } } else { value, ok := result[columnName] if !ok { return errors.New("列不存在") } oneResultValue = value } switch outputKind { case reflect.String: return reflectutils.AssignStringValue(oneResultValue, outputValue) case reflect.Bool: return reflectutils.AssignBoolValue(oneResultValue, outputValue) case reflect.Int64: return reflectutils.AssignInt64Value(oneResultValue, outputValue) case reflect.Uint64: return reflectutils.AssignUint64Value(oneResultValue, outputValue) case reflect.Float64: return reflectutils.AssignFloat64Value(oneResultValue, outputValue) case reflect.Struct: if outputValue.Type().Name() == "time.Time" { return errors.New("不支持转换到time.Time,请使用Result.ColumnValueStringAsTime") } return sql_result.DefaultUsage(result, output, columnName) default: return errors.New("不支持的类型") } }