golang通过sql排序查询出的数据,以map的形式返回,顺序乱了?

下载:

//下载csv
func doDown() {
    csvName := downDir + time.Now().Format("2006-01-02") + ".csv"
    file, _ := os.OpenFile(csvName, os.O_WRONLY|os.O_CREATE, os.ModePerm)
    w := csv.NewWriter(file)
    //防止中午乱码
    file.WriteString("\xEF\xBB\xBF")
    w.Write([]string{"标题", "更新时间", "链接"})
    pageSize := 1000
    page := 1
    db, err := mysqlUtil.CreateReadDb()
    if err != nil {
        fmt.Println("connect db err")
        os.Exit(1)
    }
    for {
        offset := (page - 1) * pageSize
        sqlStr := `select title,uptime,url from film order by uptime desc limit ` + strconv.Itoa(offset) + `,` + strconv.Itoa(pageSize)
        fmt.Println(sqlStr)
        res, err := db.Query(sqlStr)
        if err != nil {
            fmt.Println("query err ", err)
        }
        rows, err := mysqlUtil.GetRows(res)
        if len(rows) > 0 {
            for _, v := range rows {
                w.Write([]string{v["title"], v["uptime"], host + v["url"]})
            }
        } else {
            break
        }
        page++
    }
    w.Flush()
}

sql是根据uptime倒序取的数据,为啥写csv得时候,顺序都乱了呢?
打印了一下输出,发现是rows, err := mysqlUtil.GetRows(res)这个的问题。
这里贴出这个函数的代码:

func GetRows(query *sql.Rows) (map[int]map[string]string, error) {
    column, err := query.Columns()              //读出查询出的列字段名
    if err != nil {
        return nil, fmt.Errorf("getRows db err:", err)
    }
    values := make([][]byte, len(column))     //values是每个列的值,这里获取到byte里
    scans := make([]interface{}, len(column)) //因为每次查询出来的列是不定长的,用len(column)定住当次查询的长度
    for i := range values {                   //让每一行数据都填充到[][]byte里面
        scans[i] = &values[i]
    }
    results := make(map[int]map[string]string) //最后得到的map
    i := 0
    for query.Next() { //循环,让游标往下移动
        if err := query.Scan(scans...); err != nil { //query.Scan查询出来的不定长值放到scans[i] = &values[i],也就是每行都放在values里
            return nil,fmt.Errorf("scan result db err:", err)
        }
        row := make(map[string]string) //每行数据
        for k, v := range values {     //每行数据是放在values里面,现在把它挪到row里
            key := column[k]
            row[key] = string(v)
        }
        results[i] = row //装入结果集中
        i++
    }
    return results,nil
}

因为返回的是map,map是无序的,所有返回类型需要做以下调整:

func GetRowsSlice(query *sql.Rows) ([]map[string]string, error) {
    column, err := query.Columns()              //读出查询出的列字段名
    if err != nil {
        return nil, fmt.Errorf("getRows db err:", err)
    }
    values := make([][]byte, len(column))     //values是每个列的值,这里获取到byte里
    scans := make([]interface{}, len(column)) //因为每次查询出来的列是不定长的,用len(column)定住当次查询的长度
    for i := range values {                   //让每一行数据都填充到[][]byte里面
        scans[i] = &values[i]
    }
    results := []map[string]string{} //最后得到的map
    i := 0
    for query.Next() { //循环,让游标往下移动
        if err := query.Scan(scans...); err != nil { //query.Scan查询出来的不定长值放到scans[i] = &values[i],也就是每行都放在values里
            return nil,fmt.Errorf("scan result db err:", err)
        }
        row := make(map[string]string) //每行数据
        for k, v := range values {     //每行数据是放在values里面,现在把它挪到row里
            key := column[k]
            row[key] = string(v)
        }
        //results[i] = row //装入结果集中
        results = append(results, row)
        i++
    }
    return results,nil
}
阅读 5.2k
4 个回答

见问题描述,把sql查询结果以slice形式返回即可

我也遇到了 同问

你们都没看过golang的文档吧,文档都说了,map类型是无序的,千万不要当成有序的

新手上路,请多包涵

map无序的,哈哈

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题