Golang | gorm | 无预设struct的mysql查询

417 阅读1分钟

起因

项目通过使用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
}

最后

暂时的解决方法是如此, 需求是实现了, 不够也面临着很多的问题, 比如多次嵌套的 遍历存在性能问题, 如果读者有更好的解决方法欢迎评论一起讨论解决方法