最近在用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框架
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)