go提供了一套统一操作database的sql接口,任何第三方都可以通过实现相应的driver来访问感兴趣的数据库。譬如我们项目中使用的Go-MySQL-Driver

go提供了一套很好的机制来处理数据库的查询操作,譬如官方的例子:

age := 27
rows, err := db.Query("SELECT name FROM users WHERE age=?", age)
if err != nil {
log.Fatal(err)
}
for rows.Next() {
var name string
if err := rows.Scan(&name); err != nil {
log.Fatal(err)
}
fmt.Printf("%s is %d\n", name, age)
}
if err := rows.Err(); err != nil {
log.Fatal(err)
}

在上面的例子中,Query会返回一个rows,我们通过Next获取下一行数据,然后使用Scan将每行的数据设置到相应的变量上面去。

虽然这样操作查询结果集很方便,但是我们在使用过程中,发现当sql query语句过多,如果每一个查询都按照这种写法,代码量太大了。所以,我们自然就想到了封装。

db result主要进行的工作就是提供一套统一的接口供外部方便的使用查询的结果集,它主要提供了如下几个接口:

func (*Result) GetInt(row, col int) (int64, error)
func (*Result) GetIntByName(row int, colName string) (int64, error) func (*Result) GetFloat(row, col int) (float64, error)
func (*Result) GetFloatByName(row int, colName string) (float64, error) func (*Result) GetBool(row, col int) (bool, error)
func (*Result) GetBoolByName(row int, colName string) (bool, error) func (*Result) GetString(row, col int) (string, error)
func (*Result) GetStringByName(row int, colName string) (string, error) func (*Result) GetBuffer(row, col int) ([]byte, error)
func (*Result) GetBufferByName(row int, colName string) ([]byte, error)

可以看到,result的“Get*”接口通过结果集的row和col的索引来访问数据,而"Get*ByName"接口则是通过row以及col的名字来访问数据。

因为go支持很多的数据类型,为了简单起见,所有int类型的我们统一使用int64代替,外部在进行相应的数据转换。同理float类型也是用float64代替。如果查询的结果某个字段为空,result只是返回该字段默认的数值。通常情况下,我都会要求数据库中的字段都为not null,所以查询字段为null的情况这里没有过多考虑。

一个很简单的例子:

//msg_id bigint
//msg varchar(256)
res, err := Query("is", "select msg_id, msg from msg_table where msg_id in (?, ?)", 1, 2) var id1 int64
id1, err = res.GetInt(0, 0) var msg2 string
msg2, err = res.GetStringByName(1, "msg")

在上面的例子中,我们在查询的时候返回了一个result,然后通过相关的函数获取到了相应的信息。这里我们需要特别注意的就是Query后面的第一个参数“is”

Go-MySQL-Driver中,会两种结果集模式,一个是text rows,另一个则是binary rows(使用stmt query的结果集),在text rows中,所有的数据都是[]byte格式,而在binary rows中,则会根据stmt对应的结果类型转换成相应的数据。为了统一,我们通过在query的时候手动指定column
types,在row scan的时候直接创建对应的类型数据,供scan设置。如下:

func (res *Result) newValue(column int) (interface{}, error) {
t := res.ColumnTypes[column] switch t {
case Column_String:
return new(string), nil
case Column_Int:
return new(int64), nil
case Column_Bool:
return new(bool), nil
case Column_Float:
return new(float64), nil
case Column_Buffer:
return new([]byte), nil
default:
return nil, ErrColumnTypes
}
} //遍历结果集的时候,我们根据column types生成指定的value,并通过Scan设置 for rows.Next() {
dest := make([]interface{}, len(res.ColumnNames)) for i, _ := range dest {
dest[i], err = res.newValue(i)
if err != nil {
return err
}
} err = rows.Scan(dest...)
if err != nil {
return err
}

如果大家使用过mysql_stmt_bind_result,就可以发现,column types的概念其实就跟设置MYSQL_BIND差不多,只是result为了简单,只支持int64,float64,bool,string,以及[]byte这几种类型。

具体的代码在这里https://github.com/siddontang/qpush/blob/master/go/src/lib/db/result.go

my golib:db query Result的更多相关文章

  1. lr数据库参数化取数:The query result is empty and same is the parameter file问题原因

    出现这个问题的原因: 是因为我们的查询结果存在中文 如果查询结果没有中文,显示正常 解决办法: 新建一个数据源: 重新再选择这个数据源,再次查询: 说明不是连接字符串的问题或者是mysql驱动的问题 ...

  2. mybatis使用map传递多参数报错:A query was run and no Result Maps were found for the Mapped Statement

    在使用mybatis进行多参数传递时,报错: A query was run and no Result Maps were found for the Mapped Statement 'xx.xx ...

  3. mybatis报错:A query was run and no Result Maps were found for the Mapped Statement、、Property [login_ip] not found on type [com.thinkgem.jeesite.common.permission.entity.PremissUser]问题解决

    今天在做ssm项目的时候出现了: 先是出现 了错误: mybatis报错:A query was run and no Result Maps were found for the Mapped St ...

  4. Data access between different DBMS and other txt/csv data source by DB Query Analyzer

        1 About DB Query Analyzer DB Query Analyzer is presented by Master Genfeng,Ma from Chinese Mainl ...

  5. How to generate the complex data regularly to Ministry of Transport of P.R.C by DB Query Analyzer

    How to generate the complex data regularly to Ministry of Transport of P.R.C by DB Query Analyzer 1 ...

  6. The 1st tip of DB Query Analyzer

     The 1st tip of DB Query Analyzer               Ma Genfeng   (Guangdong Unitoll Services incorporate ...

  7. The 6th tip of DB Query Analyzer

      The 6th tip of DB Query Analyzer MA Gen feng (Guangdong Unitoll Services incorporated, Guangzhou ...

  8. The 5th tip of DB Query Analyzer

    The 5th tip of DB Query Analyzer             Ma Genfeng   (Guangdong UnitollServices incorporated, G ...

  9. Save results to different files when executing multi SQL statements in DB Query Analyzer 7.01

        1 About DB Query Analyzer DB Query Analyzer is presented by Master Genfeng,Ma from Chinese Mainl ...

随机推荐

  1. 实验与作业(Python)-02 Python函数入门与温度转换程序

    截止日期 实验目标 学会定义函数,使用函数.学会导入在某个文件中定义的函数. input获得值,然后通过eval或者int.float将其转换为相应的类型. 学会使用列表:访问列表.append.遍历 ...

  2. 异步请求引发的Chrome死锁

    浏览器支持的并发异步请求数目是有限的,当需要的资源过多时候(远远大于并发数目),就需要自己管理XHR请求. 在实现自己的XHR的Manger时候,当请求数目达到2000多的时候,经常会遇到chrome ...

  3. Retrofit,Okhttp对每个Request统一动态添加header和参数(五)

    文/Tamic 地址:http://blog.csdn.net/sk719887916/article/details/52189602 Header How to Add header to Eve ...

  4. 递归dict

    一个看起来非常酷的定义 class Example(dict): def __getitem__(self, item): try: return dict.__getitem__(self, ite ...

  5. Java异常处理-----java异常体系

    再三思考后还是决定贴图,csdn的格式,我是真玩不转,对不起了各位,继续将就吧. 错误原因:内存溢出.需要的内存已经超出了java虚拟机管理的内存范围. 错误原因:找不到类文件. 错误(Error): ...

  6. android:shape属性详解

    这一类的shape定义在xml中 file location: res/drawable/filename.xml The filename is used as the resource ID.(这 ...

  7. 混合开发(一)——WebView开发高级技巧之加载网页以及JavaScript,加载进度条

    混合开发(一)--WebView开发高级技巧之加载网页以及JavaScript,加载进度条 现在关于混合开发也越来越多了,很多人喜欢跟随,比如HB,比如RN,其实这东西很早就有这么一个概念了,而且说实 ...

  8. (一二四)tableView的多组数据展示和手动排序

    最近在写一个轻量级的网络游戏,遇到了技能优先顺序手动排序的需求,我就想到了iOS自带的tableView编辑功能,对其进行了初步探索,最后做出的效果如下图所示: 点击左边可以删除,拖住右边可以手动排序 ...

  9. 随机采样和随机模拟:吉布斯采样Gibbs Sampling实现高斯分布参数推断

    http://blog.csdn.net/pipisorry/article/details/51539739 吉布斯采样的实现问题 本文主要说明如何通过吉布斯采样来采样截断多维高斯分布的参数(已知一 ...

  10. acm入门搜索-石油数目

    题意:给出一个N*M的矩形区域和每个区域的状态--有/没有石油,(定义)如果两个有石油的区域是相邻的(水平.垂直.斜)则认为这是属于同一个oil pocket. 求这块矩形区域一共有多少oilpock ...