mysql数据列动态变化_Golang读取MySQL数据库,数据列动态变化的处理

正巧我前几天研究这个问题。

我的解法不知道很好,不过解决了我的问题。

如果有专业人士,也请大家给出更完美的方案。

主要就是用了类型查询,得到内部实际类型,然后自己去构造指针放到`Scan`前的slice里面,

再调用 `rows.Scan(arr ... )` 去获取实际数据,

最终将内部的数据再通过反射取出来。

```go

package main

import (

"bytes"

"database/sql"

"fmt"

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

)

/*

mysql> desc users;

+-------------+--------------+------+-----+---------+----------------+

| Field | Type | Null | Key | Default | Extra |

+-------------+--------------+------+-----+---------+----------------+

| id | int(11) | NO | PRI | NULL | auto_increment |

| username | varchar(40) | NO | | NULL | |

| password | varchar(256) | NO | | NULL | |

| create_time | datetime | NO | | NULL | |

+-------------+--------------+------+-----+---------+----------------+

4 rows in set (0.01 sec)

mysql> select * from users;

+----+----------+----------+---------------------+

| id | username | password | create_time |

+----+----------+----------+---------------------+

| 1 | aa | aa | 2018-12-01 00:00:00 |

| 2 | bb | bb | 2018-12-02 00:00:00 |

| 3 | cc | cc | 2018-12-03 00:00:00 |

| 4 | dd | dd | 2018-12-04 00:00:00 |

+----+----------+----------+---------------------+

4 rows in set (0.00 sec)

*/

func withReflect() {

db, err := sql.Open("mysql", "go:go@/go")

if err != nil {

fmt.Println("open db failed")

return

}

rows, err := db.Query("select * from users")

if err != nil {

fmt.Println("query db failed")

return

}

defer rows.Close()

colTypes, err := rows.ColumnTypes()

if err != nil {

fmt.Println("coltypes failed")

return

}

var data = make(map[uint32]interface{})

for rows.Next() {

var id uint32

var built = make([]interface{}, 0)

built = append([]interface{}{&id})

for _, ct := range colTypes[1:] {

switch ct.DatabaseTypeName() {

case "VARCHAR":

fallthrough

case "DATETIME":

built = append(built, new(string))

default:

var i interface{}

built = append(built, &i)

fmt.Printf("type name is %v\n", ct.DatabaseTypeName())

}

}

err = rows.Scan(built...)

if err != nil {

fmt.Println(err)

continue

}

data[id] = built[1:]

}

for k, v := range data {

ss := &bytes.Buffer{}

vlist := v.([]interface{})

for _, tt := range vlist {

switch realStr := tt.(type) {

case *string:

fmt.Fprintf(ss, "%v, ", *realStr)

default:

fmt.Fprintf(ss, "uknown, ")

}

}

fmt.Printf("k = %v, v = %v\n", k, ss.String())

}

return

}

func main() {

withReflect()

}

```

#2

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值