go 结构体转化为string_go 通过字符串访问结构体

在使用 orm 操作数据的过程中,gorm 使用 struct 对数据库中的表进行定位。虽然虽然可以 一个表定义一套 增删查改 但是感觉需要的代码量比较多。所以我决定通过字符串访问结构体已应对简单的 增删查改。

这里简单的介绍一下原理新建一个 map ,key 为我们使用的字符串 value 为反射类型,在使用的时候从 map 中取出值,然后通过反射新建出需要使用的类型

这里我先简单声明一下,然后在对它进行封装,以方便我们之后的使用

package main

import (

"encoding/json"

"fmt"

"reflect"

)

type Test struct { // 我们需要使用到的结构体

Name string `json:"name"`

}

func main() {

temp := make(map[string]reflect.Type) // 建立一个类似于模板仓库的东西

temp["test"] = reflect.TypeOf(Test{}) // 将类型转换成反射类型在需要使用的时候通过反射新建对应实例

// 上面是如何存储

//-----------------------

// 接下来就是如何取出来了

t, ok := temp["test"] // 检查元素是否真实存在

if !ok {

panic("test 结构体未进行储存") // 这里只是演示实际处理根据你的真实使用情况来定

}

fmt.Printf("%T\n", t) // 检查一下类型司机上并没有哦什么用

// 通过反射新建实例并转成 interface 别问我为什么这样写 如果放进去的是一个 对应类型的 interface 再反射出来使用,在第二次使用时携带上一次的值(不是本次使用的方式)

foo := reflect.New(t).Interface() // 类似于 new(type) 因为下一步会使用反射将值放进去

fmt.Printf("%T\n", foo) // 检测一下即将使用的类型

// 类型新建好后对它进行赋值

// 使用 json 解析将值放进去当然你也可以使用反射 不过我觉得这种方式更简单

m := map[string]interface{}{"name": "niconiconi"}

res, err := json.Marshal(m)

if err != nil {

panic(err)

}

if err := json.Unmarshal(res, foo); err != nil {

panic(err)

}

fmt.Printf("type == %T | value == %v\n", foo, foo) // 检测一下类型以及值

// 到这里就结束了

}

在上面了例子中演示了,如何通过 string 访问 struct 当然在实际使用中是可能会有多个 model 需要使用我们都把它塞进 map 就好了。

为了方便使用我们可以对上面的例子加一点点细节,类似于下面这样

// 在使用之前 调用 New 函数新建工厂

// Add 方法 放入你需要的类型

// Get("typeName") 获取你需要的类型

package factory

import (

"fmt"

"reflect"

"strings"

)

// Store 模板实体

type Store struct {

temp map[string]reflect.Type

}

// Add 添加(需要 非指针)

func (m *Store) Add(in ...interface{}) {

if m.temp == nil {

m.temp = make(map[string]reflect.Type)

}

for _, v := range in {

refType := reflect.TypeOf(v)

split := strings.Split(refType.String(), ".")

name := strings.ToLower(split[len(split)-1])

m.temp[name] = refType

}

}

// Get 获取一个新的模板(指针类型)

func (m Store) Get(name string) (interface{}, error) {

layout, ok := m.temp[name]

if !ok {

return nil, fmt.Errorf("%s does not exist", name)

}

temp := reflect.New(layout).Interface()

return temp, nil

}

// New 新建

func New() Store {

return Store{}

}

使用方式类似于下面这样,注意不是真实代码

package main

var prop = factory.New()

func init() {

prop.Add(user{}, file{})

}

func foo() (interface{}, int46 ,error) {

tableS := "user" // 外部获取

rows, err := prop.Get(tableS)

if err != nil{

return, 0, err

}

// 然后使用上面例子中 json 的方式放进去 或者 给其他 组件使用

//err = db.X().Model(local).Where(kvs).Count(&total).Order(sort).Offset((pi - 1) * ps).Limit(ps).Find(rows).Error

//return rows, total, err

}

在这里提供一个 gorm 的查询思路 表 从 uri 中获取 查询条件 使用 url ? 后面的 字符串(也叫查询条件)并将其转换成 map 塞进 gorm 的查询条件结果映射回我们 上面封装的方法获取的模板。

需要一个 我们就放一个 struct 需要 []struct 那就放 []struct 进去 全程不需要一条 SQL 语句 真香。

最后祝你玩得开心 (*^_^*)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值