下载:
//下载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
}
见问题描述,把sql查询结果以slice形式返回即可