gorm 不需要结构体也能获取数据

755 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第八天,点击查看活动详情

gorm 不需要结构体也能获取数据

gorm不使用结构体真的真的真的在很多地方都会受阻,这也就比较难实现一些需要动态获取数据的需求

可能网上有很多人说用map和interface{}进行结合的话就可以了,但是有些地方有效,但这个的弊端或许就不用多说了.go虽然有interface{}但是感觉他和python的随机类型来比,还是相差基本大吧,不过也有可能是go是编译型语言,python是解释语言什么的,从而造成的限制. 废话也不多说了,接下来就讲解一下困扰我一下的问题

gorm 只知道表名,没有结构体,后端要怎么返回数据给前端

看到不用结构体,很多人可能就会比较惊讶,因为如果你用多了orm或者其他的都会知道一点,Scan函数里面必须传切片或者结构体,而且你如果用切片好像也只能获取某一列的数据,并不能获取所有列的数据.没错用传统的方法确实是无法实现,所以只能看源码,找Scan执行的流程,不出意外,看着看着就头大了.

image.png

看了很久的源码,最后发现如果一步一步看的话基本上就完了,因为我就是一步一步看发现Set以后基本上都没啥用,因为gorm:query_destination其实基本上对结构体进行判断,字段映射相关的,所以突破点也就只有NewScope,但是在分析NewScope时发现到了原来gorm也能调用database/sql里面的查询也就是Query函数

image.png

但是能调用原生确实不需要用到结构体但是会出现一个很严重的问题就是需要变量,而且是已经定好类型的变量,如果看不懂则可以去看看Query介绍

如何获取到类型,并进行定义变量

想到这个问题,我想了几种方法

  1. 结构体动态添加字段(不可能,目前看了很多文章都不支持,我还想着reflect或许可以,但是最终还是失败了!!!
  2. 能不能获取到字段的类型,动态定义变量(能获取字段类型,但是动态定义变量,目前未看到有什么方案)
  3. sql.RawBytes结合Rows.Scan实现获取结果(成功,但是有一点缺陷就是返回的都是字符串,这也是临时的解决方案,后续如果还有更好方案则会更新文章)

sql.RawBytes结合Rows.Scan实现获取结果

原理比较简单

  1. Rows.Columns()获取表的所有字段
  2. 再将所有的字段存入results([][]string)二维数组中
  3. 定义二个切片负责将Scan里面的值取出来
  4. 最后将值存入到一个make(map[string]interface{})

Rows.Columns()获取表的所有字段

image.png

再将所有的字段存入results([][]string)二维数组中

image.png

定义二个切片负责将Scan里面的值取出来

image.png

最后将值存入到一个make(map[string]interface{})

image.png

得到的结果

image.png