golang有没有那种 查询数据库,直接返回 map[string]interface{} 或者类似的类型?

happy321 · 2023-05-11 17:36:49 · 4171 次点击 · 大约8小时之前 开始浏览    置顶
这是一个创建于 2023-05-11 17:36:49 的主题,其中的信息可能已经有所发展或是发生改变。

for rows.Next() { var data string err = rows.Scan(&data) if err != nil { panic(err.Error()) } results = append(results, data) }

类似这种 Scan 里面的个数和select的个数都要一致

请问有没有性能高的 且 直接返回数组或者map的方法??


有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

4171 次点击  
加入收藏 微博
16 回复  |  直到 2023-06-19 14:06:09
sanrentai
sanrentai · #1 · 2年之前

goframe这个库能完全满足

happy321
happy321 · #2 · 2年之前
sanrentaisanrentai #1 回复

goframe这个库能完全满足

可以发下url地址吗? 没找到

zxnhl702
zxnhl702 · #3 · 2年之前

xorm有个query、queryString、queryInterface应该能满足你的要求 https://pkg.go.dev/xorm.io/xorm

GGXXLL
GGXXLL · #4 · 2年之前

gorm 呀

sanrentai
sanrentai · #5 · 2年之前
happy321happy321 #2 回复

#1楼 @sanrentai 可以发下url地址吗? 没找到

tangtanglove
tangtanglove · #6 · 2年之前

不建议直接扫描到map[string]interface{}里,不容易排除错误

happy321
happy321 · #7 · 2年之前
tangtanglovetangtanglove #6 回复

不建议直接扫描到map[string]interface{}里,不容易排除错误

不容易排错,可以帮忙举个例子吗?

xiangbei
xiangbei · #8 · 2年之前

我是定义struct 返回 容易排错

tangtanglove
tangtanglove · #9 · 2年之前
happy321happy321 #7 回复

#6楼 @tangtanglove 不容易排错,可以帮忙举个例子吗?

例如数据库字段名更改,数据扫描到map里,如果忘记更改map的下标,程序也不会提示错误

GGXXLL
GGXXLL · #10 · 2年之前

而且,如果数据层就返回一个map的话,这个map在其他层各种修改使用,需要进行interface断言转类型。尤其是代码时间越长,业务越复杂,你自己也不记得这个map会是什么样,导致你只能打印map来确定其中的内容,不好debug和维护。

happy321
happy321 · #11 · 2年之前

谢谢各位

happy321
happy321 · #12 · 2年之前

主要是想后期维护 添加字段方便一点的 请问要是用结构体的话 从数据库查询出来后,会一个个类型转换为结构体的类型吗?

GGXXLL
GGXXLL · #13 · 2年之前

很多在用 https://gorm.io/zh_CN/docs/index.html ,你可以看看合适不

happy321
happy321 · #14 · 2年之前
GGXXLLGGXXLL #13 回复

很多在用 https://gorm.io/zh_CN/docs/index.html ,你可以看看合适不

谢谢 但是在网上查到 这个速度比 原生的库慢好多 请问这个实际场景,慢得明显吗?

jan-bar
jan-bar · #15 · 2年之前

看这问题挂了好几天了,搜了下go官方源码,里面相关xxx_test.go里面就有你想要的东西,我这里搞了个通用查询,查询结果你需要自己想办法处理一下。

package main

import (
    "database/sql"
    "flag"
    "fmt"
    "reflect"

    _ "github.com/go-sql-driver/mysql"
)

func main() {
    dns := flag.String("m", "user:pass@tcp(ip:port)/db?charset=utf8&parseTime=true&loc=Local", "")
    flag.Parse()
    err := mysql(*dns)
    if err != nil {
        panic(err)
    }
}

func mysql(dsn string) error {
    db, err := sql.Open("mysql", dsn)
    if err != nil {
        return err
    }
    defer db.Close()

    rows, err := db.Query("select * from test limit 5")
    if err != nil {
        return err
    }
    defer rows.Close()

    cts, err := rows.ColumnTypes()
    if err != nil {
        return err
    }

    var (
        ctLen = len(cts)
        types = make([]reflect.Type, ctLen)
        names = make([]string, ctLen)
    )
    for i, tp := range cts {
        st := tp.ScanType()
        if st != nil {
            types[i] = st
            names[i] = tp.Name()
        }
    }

    var resp []map[string]any
    for rows.Next() {
        values := make([]any, ctLen)
        for i := range values {
            values[i] = reflect.New(types[i]).Interface()
        }

        err = rows.Scan(values...)
        if err != nil {
            return err
        }

        tmp := make(map[string]any, ctLen)
        for i, v := range values {
            // 注意列可以为NULL的值会解析为sql.Nullxxx
            // []byte和string会被解析为sql.RawBytes
            tmp[names[i]] = reflect.ValueOf(v).Elem().Interface()
        }
        resp = append(resp, tmp)
    }

    fmt.Println(resp)
    return nil
}
happy321
happy321 · #16 · 2年之前

谢谢各位~~

添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传