起因
项目通过使用protobuf 序列化反序列传递数据, c/s架构, server端对于mysql的表是无感知的,无法通过预设表结构体操作mysql 关系型数据库.
分析
-
没有表结构,无法用传统的gorm方式去操作mysql表
-
和client端同时协商沟通, 返回数据([]byte类型),但是需要返回数据类型,字段名
发现gorm db.Raw(sql).Rows() 返回的对象中有字段名与数据类型,so 只需拿到查询数据即可
代码
func GetRowsReturn(rows *sql.Rows) (resp []*dsproto.LineRecord, err error) {
columns, err := rows.Columns() //拿到查询到数据的字段
if err != nil {
return
}
_type, err := rows.ColumnTypes() //拿到字段类型包括字段名,值类型等
if err != nil {
return
}
length := len(columns)
var dest []interface{} //承接scan之后的数据
for i := 0; i < length; i++ {
dest = append(dest, new(interface{}))
}
for rows.Next() {
rows.Scan(dest...)
}
var singleData dsproto.LineRecord
for k, _ := range dest { //开始赋值
var field dsproto.FieldPair
v := *dest[k].(*interface{})
field.Key = _type[k].Name()
field.Type = returnFieldType(_type[k].DatabaseTypeName())
field.Value = v.([]byte)
singleData.Field = append(singleData.Field, &field)
resp = append(resp, &singleData)
}
return
}
最后
暂时的解决方法是如此, 需求是实现了, 不够也面临着很多的问题, 比如多次嵌套的 遍历存在性能问题, 如果读者有更好的解决方法欢迎评论一起讨论解决方法