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. 利用JAVA多线程来提高数据处理效率

    肿瘤大数据挖掘中经常需要处理上百亿行的文本文件,这些文件往往高达数百GB,假如文件结构简单统一,那么用sed和awk 处理是非常方便和快速的.但有时候会遇到逻辑较为复杂的处理流程,这样我一般会用JAV ...

  2. MySQL 数学函数

    MySQL 数学函数 所有的数学函数在发生错误的情况下,均返回 NULL. -元减.改变参数的符号 mysql> SELECT - 2; -> -2 注意,如果这个操作符被用于一个 BIG ...

  3. Jmeter(六)_前置处理器

     BeanShell PreProcessor  使用BeanShell在请求进行之前进行操作.语法使用与BeanShell Sampler是一样的.但可使用的内置变量稍有不同 参考示例 Jmeter ...

  4. docker volume创建、备份、nfs存储

    docker存储volume #环境 centos7.4 , Docker version 17.12.0-ce docker volume创建.备份.nfs存储 #docker volume 数据存 ...

  5. 使用GDAL进行RPC坐标转换

    使用GDAL进行RPC坐标转换 对于高分辨率遥感卫星数据而言,目前几乎都提供了有理函数模型(RFM)来进行图像校正(SPOT系列提供了有理函数模型之外还提供了严格轨道模型).对遥感影像进行校正目前最常 ...

  6. 20160216.CCPP体系详解(0026天)

    程序片段(01):01.MemCpy.c 内容概要:内存拷贝 #include <stdio.h> #include <stdlib.h> #include <memor ...

  7. Hadoop2动态调整Log级别-以datanode的heartbeat log为例

    在Hadoop中,有些log信息在正常情况下是不打印出来的.比如datanode发送heartbeat的日志. 代码位于BPServiceActor#sendHeartBeat方法中,如下图: 由于默 ...

  8. log file sync 因为数据线有问题而造成高等侍的表现

    这是3月份某客户的情况,原因是服务器硬件故障后进行更换之后,业务翻译偶尔出现提交缓慢的情况.我们先来看下awr的情况. 我们可以看到,该系统的load profile信息其实并不高,每秒才21个tra ...

  9. Mac小技巧:强制退出程序的六种方法

    原帖地址: http://www.cnbeta.com/articles/175447.htm 1.使用键盘快捷键强制退出处于活跃状态的Mac程序 快捷键:Command+Option+Shift+E ...

  10. 微信小程序基础之试图控件View、ScrollView、Swiper

    今天写一篇关于微信小程序视图控件的文章,主要是介绍界面的搭建和部分操作js交互功能的介绍,转载请注明出处,谢谢~ 首先显示首页结构.创建三个navigator,用来跳转页面: <!--index ...