golang sqlx rows.Next() scan扫描列表和一行

最近在用clickhouse,对于sql包,我用github.com/jmoiron/sqlx包替代了database/sql,但是查询时只能返回sqlx.Rows迭代对象要自己去Next(),获取一行时也用的是sqlx.Row。

所以想写个函数自动把rows转换成struct列表或map列表,查询一行也类似。不需要每次都要自己Next()。

现在分享下来。

1、扫描多行结果

(1)新建一个rows处理类

package clickhouses

import (
	"github.com/jmoiron/sqlx"
	"reflect"
)

type ClickhouseRows struct {
}

//Scan 扫描结果
func (r *ClickhouseRows) Scan(rows *sqlx.Rows, dest interface{}) error {
    var err error 

	arr := reflect.ValueOf(dest).Elem()
	valueType := reflect.TypeOf(dest).Elem().Elem()
	v := reflect.New(valueType)

	switch v.Interface().(type) {
	//Map格式
	case *map[string]interface{}:
		for rows.Next() {
			v := reflect.MakeMap(valueType)
            err = rows.MapScan(v.Interface().(map[string]interface{}))
			if err == nil {
				arr.Set(reflect.Append(arr, v))
			}
		}
	//结构体类型
	default:
		for rows.Next() {
			v := reflect.New(valueType)
            err = rows.StructScan(v.Interface())
			if err == nil {
				arr.Set(reflect.Append(arr, v.Elem()))
			}
		}
	}

    return err
}

(2)应用实例:

//连接数据库
db, err := sqlx.Open("clickhouse", "tcp://127.0.0.1:9000?debug=true")

if err != nil {
   panic(err)
}

//查询
rows, err := db.Queryx("SELECT * FROM users WHERE status = ?", 1)

if err != nil {
   panic(err)
}

//第1种、查询结果为结构体
type UserModel struct {
	Id int `db:"id"`
    Username string `db:"username"`
}

var structData []UserModel
new(ClickhouseRows).Scan(rows, &structData)

//第2种、查询结果为map结构
var mapData []map[string]interface{}
new(ClickhouseRows).Scan(rows, &mapData)

2、扫描一行结果

先新建sqlx.Row的处理类

注:请注意我这里的ClickhouseRow没有s结尾。

package clickhouses

import (
	"github.com/jmoiron/sqlx"
	"reflect"
)

type ClickhouseRow struct {
}

func (r *ClickhouseRow) Scan(row *sqlx.Row, dest interface{}) error {
    var err error

	valueType := reflect.TypeOf(dest).Elem()
	v := reflect.New(valueType)

	switch v.Interface().(type) {
	//Map格式
	case *map[string]interface{}:
		v := dest.(*map[string]interface{})
		err = row.MapScan(*v)
	//结构体类型
	default:
		err = row.StructScan(dest)
	}
   
    return err
}
//查询一行
row := db.QueryRowx("SELECT * FROM users WHERE status = ?", 1)

//第1种、查询结果为结构体
type UserModel struct {
	Id int `db:"id"`
    Username string `db:"username"`
}

var structRow UserModel
new(ClickhouseRow).Scan(row, &structRow)

//第2种、查询结果为map结构
mapRow := map[string]interface{}{}
new(ClickhouseRow).Scan(row, &mapRow)

关注PHP的特色框架 :Ocara框架

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:编程工作室 设计师:CSDN官方博客 返回首页
评论

打赏作者

nakeer

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值