做这个的需求是这样的,我在写一个数据组件,用来统一多个类型数据库的组件,简单的说就是通过tcp请求传入一个SQL语句,就会返回类似于mysql的相应结果,同时可以确保MySQL,Redis的数据一致性,初衷是为了减少MySQL的查询次数。
而最初的查询返回统一是一个map数组,也就是[]map[string]interface{}
,但有一个问题就是,客户端拿到数据后,需要对类型进行断言,这里参考了orm的源码,以及网上的一些文章,然后用反射完成了单个结构体赋值,也就是orm中的err := o.Read(&user)
,做数组时参考了orm中的func (o *rawSet) QueryRows(containers ...interface{}) (int64, error)
遇到的问题:
CanSet()方法返回false:解决方法就是传地址,这里所有的Can类型检测方法就是针对当前的reflect.Value进行校验,如果是一个地址类的value,那就可以进行相应的修改。
结构体赋值问题:要想访问结构体中的字段,有一个大前提条件就是首字母大写,而正常情况下MySQL存储的字段是下划线连接的小写字母,通过json包转换为golang的字段就变成了驼峰,但首字母是小写,这时候就要进行首字母处理。
数组增加元素:首先是要通过反射获取到数组元素的类型,然后通过类型去new一个结构体的实例出来,这里用到了
reflect.New()
方法,同时在最后的时候,要进行深度拷贝才可以将数组完全赋值给传进来的地址上。
代码如下:
package main |
END