前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >go:将mysql返回数据转换为一个字典数组

go:将mysql返回数据转换为一个字典数组

作者头像
超级大猪
发布2019-11-22 00:15:26
2.4K0
发布2019-11-22 00:15:26
举报
文章被收录于专栏:大猪的笔记大猪的笔记

go官方库返回的是一个rows对象,非常蛋疼。 写了一个很神奇的函数,把返回值db.Rows转换成[]map[string]interface{}结构。

代码语言:javascript
复制
package main

import (
    "database/sql"
    "fmt"
    "github.com/go-sql-driver/mysql"
    "log"
    "math"
    "reflect"
    "strconv"
    "strings"
)

func main() {
    db, err := sql.Open("mysql", "root:123456@tcp(127.0.0.1:3306)/db_viewlib?charset=utf8&parseTime=True")
    if err != nil {
        log.Fatal(err)
    }
    defer db.Close()

    sql := "select * from t_attr_1400face_common limit 1000"
    dbRows, err := db.Query(sql)
    if err != nil {
        fmt.Printf("query err %v", err)
    }

    rows := RowsToMap(dbRows)
    for _, item := range rows {
        fmt.Println(item)
    }
}

var BytesKind = reflect.TypeOf(sql.RawBytes{}).Kind()
var TimeKind = reflect.TypeOf(mysql.NullTime{}).Kind()

func checkErr(err error) {
    if err != nil {
        fmt.Printf("checkErr:%v", err)
    }
}

func ToStr(strObj interface{}) string {
    switch v := strObj.(type) {
    case string:
        return v
    case []byte:
        return string(v)
    case nil:
        return ""
    default:
        return fmt.Sprintf("%v", strObj)
    }
}

func ToInt(intObj interface{}) int {
    // 假定int == int64,运行在64位机
    switch v := intObj.(type) {
    case []byte:
        return ToInt(string(v))
    case int:
        return v
    case int8:
        return int(v)
    case int16:
        return int(v)
    case int32:
        return int(v)
    case int64:
        return int(v)
    case uint:
        return int(v)
    case uint8:
        return int(v)
    case uint16:
        return int(v)
    case uint32:
        return int(v)
    case uint64:
        if v > math.MaxInt64 {
            info := fmt.Sprintf("ToInt, error, overflowd %v", v)
            panic(info)
        }
        return int(v)
    case float32:
        return int(v)
    case float64:
        return int(v)
    case string:
        strv := v
        if strings.Contains(v, ".") {
            strv = strings.Split(v, ".")[0]
        }
        if strv == "" {
            return 0
        }
        if intv, err := strconv.Atoi(strv); err == nil {
            return intv
        }
    }
    fmt.Printf(fmt.Sprintf("ToInt err, %v, %v not supportted\n", intObj,
        reflect.TypeOf(intObj).Kind()))
    return 0
}

func RowsToMap(rows *sql.Rows) []map[string]interface{} {
    result := make([]map[string]interface{}, 0)

    for rows.Next() {
        cols, err := rows.Columns()
        checkErr(err)

        colsTypes, err := rows.ColumnTypes()
        checkErr(err)

        dest := make([]interface{}, len(cols))
        destPointer := make([]interface{}, len(cols))
        for i := range dest {
            destPointer[i] = &dest[i]
        }

        err = rows.Scan(destPointer...)
        checkErr(err)

        rowResult := make(map[string]interface{})
        for i, colVal := range dest {
            colName := cols[i]
            itemType := colsTypes[i].ScanType()
            //fmt.Printf("type %v \n", itemType)

            switch itemType.Kind() {
            case BytesKind:
                rowResult[colName] = ToStr(colVal)

            case reflect.Int, reflect.Int8,
                reflect.Int16, reflect.Int32, reflect.Int64,
                reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:

                rowResult[colName] = ToInt(colVal)

            case TimeKind:
                fmt.Println("time", colVal, reflect.TypeOf(colVal))
                rowResult[colName] = ToStr(colVal)
            default:
                rowResult[colName] = ToStr(colVal)
            }
        }
        result = append(result, rowResult)
    }
    return result
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-06-28 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档