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

golang sqlx rows.Next() scan扫描列表和一行,第1张

最近在用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框架

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/996053.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-21
下一篇 2022-05-21

发表评论

登录后才能评论

评论列表(0条)

保存