关于批量查询文件元信息和更新文件元信息的问题

来源:3-8 本章小结

慕设计9360712

2021-03-24

老师你好:看了您第三章的代码后有以下两个问题,希望您回答:
1.代码里更新和上传文件元信息用的都是同一个 函数OnFileUploadFinished,这个函数的SQL语句是这样写的,
“insert ignore into tbl_file (file_sha1,file_name,file_size,file_addr,status) values (?,?,?,?,1)”)
我的个人理解是,如果是上传文件元信息,这个SQL语句没有问题,但是更新元信息的时候这个SQL语句带有ignore,我看了这个表的UNIQUE KEY idx_file_hash (file_sha1),那这样是否会因为这个ignore导致元信息无法更新,毕竟更新元信息的时候只换了名字。应该是UNIQUE KEY换成file_name才能更新成功吧。

2.第三章和第四章中批量获取文件元信息的代码不同,第四章为什么要这么写?第四章的多的两行是干嘛的。而且循环判定条件为什么要带上i<len(Values)
cloums,_:=rows.Columns()
Values:=make([]sql.RawBytes,len(cloums))

第三章:
for rows.Next() {
tfile := TableFile{}
err = rows.Scan(&tfile.FileHash, &tfile.FileAddr,
&tfile.FileName, &tfile.FileSize)
if err != nil {
fmt.Println(err.Error())
break
}
tfiles = append(tfiles, tfile)
}

第四章:
cloums,_:=rows.Columns()
Values:=make([]sql.RawBytes,len(cloums))
var tfiles []TableFile
for i:=0;i<len(Values) && rows.Next();i++{
tfile:=TableFile{}
err=rows.Scan(&tfile.FileHash,&tfile.Filename,&tfile.FileSize,&tfile.FileAddr)
if err!=nil{
fmt.Println(err.Error())
break
}
tfiles=append(tfiles,tfile)
}
fmt.Println((len(tfiles)))
return tfiles,nil
}

写回答

2回答

xiaomo

2021-04-01

同学你好,

1) tbl_file表只需要保留第一条上传记录就可以,tbl_file表的主要作用是保持文件的唯一性以及文件的存储路径;对于不同的用户来说,主要从tbl_user_file表获取文件元信息,包括文件的file_name等。

2)抱歉这里代码应该有问题-_-|,先参照第三章的用法,这边确认修正后马上更新。这里的

cloums,_:=rows.Columns()
values:= make([]sql.RawBytes,len(cloums))

主要是为了在Scan时将切片作为可变参数传入,具体可参考https://git.imooc.com/coding-323/filestore-server/src/charter4/db/mysql/conn.go中的ParseRows方法:

func ParseRows(rows *sql.Rows) []map[string]interface{} {
// 获取记录列(名)
columns, _ := rows.Columns()
// 创建列值的slice (values),并为每一列初始化一个指针
// scanArgs用作rows.Scan中的传入参数
scanArgs := make([]interface{}, len(columns))
values := make([]interface{}, len(columns))
for j := range values {
scanArgs[j] = &values[j]
}

// record为每次迭代中存储行记录的临时变量
record := make(map[string]interface{})
// records为函数最终返回的数据(列表)
records := make([]map[string]interface{}, 0)
// 迭代行记录
for rows.Next() {
//每Scan一次,将一行数据保存到record字典
err := rows.Scan(scanArgs...)
checkErr(err)

for i, col := range values {
if col != nil {
record[columns[i]] = col
}
}
records = append(records, record)
}
return records
}


0
1
慕设计9360712
非常感谢!
2021-04-06
共1条回复

xiaomo

2021-04-01

之前已经在master分支已经将代码修正过了;现其余分支也修正了过来~~十分感谢

0
0

Go实战仿百度云盘-实现企业级分布式云存储系统

紧随“云时代”技术潮流,分布式云存储系统,做第一代云程序员

1077 学习 · 494 问题

查看课程