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. @RequestBody注解用法

    做Java已经有8个多月了,但是基本没有学习过Java语言,因此在项目中写代码基本靠的是其他语言的基础来写Java代码,写出来的很多代码虽然能用,但是感觉很不地道,虽然从来没有同事说过,但是我自己觉得 ...

  2. Docker配置文件

    Docker 的 Registry 利用配置文件提供了一些仓库的模板(flavor),用户可以直接使用它们来进行开发或生产部署. 模板 在 config_sample.yml 文件中,可以看到一些现成 ...

  3. Python3 错误和异常

    Python有两种错误很容易辨认:语法错误和异常. 语法错误 Python 的语法错误或者称之为解析错,是初学者经常碰到的,如下实例 >>> while True print('He ...

  4. Python3 字典

    字典是另一种可变容器模型,且可存储任意类型对象. 字典的每个键值(key=>value)对用冒号(:)分割,每个对之间用逗号(,)分割,整个字典包括在花括号({})中 ,格式如下所示: d = ...

  5. Android Multimedia框架总结(二十五)MediaProjection实现手机截屏(无须root)

    转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/53966818 前言:一年半多以前 ...

  6. CentOS环境下使用GIT基于Nginx的私服搭建全过程

    阅读本文前你必须预先装好CentOS并且已经安装和配置好Nginx了. 安装GIT私服套件 安装centos6.5-centos7.0 安装nginx yum install -y?git gitwe ...

  7. 【SSH系列】深入浅出spring IOC中三种依赖注入方式

    spring的核心思想是IOC和AOP,IOC-控制反转,是一个重要的面向对象编程的法则来消减计算机程序的耦合问题,控制反转一般分为两种类型,依赖注入和依赖查找,依赖什么?为什么需要依赖?注入什么?控 ...

  8. MS Office2016留下的坑

    背景 问题源自论坛用户反馈,他用管家有几年了,之前使用IE都很正常,没有任何问题,但是最近突然发现,启动IE时,就会出现系统错误提示:无法启动此程序,因为计算机中丢失 api-ms-win-core- ...

  9. Appium移动自动化测试(三)--安装Android模拟器(建议直接连手机,跳过此步)

    转自虫师,亲测有效,留备后用. 本文中如果直接安装时不出现错误,则可以忽略(一.二.三.四.五),我安装的是5.1.1,直接成功,就是有点慢,要有耐心. 如果到最后一步,启动不起来,报错: emula ...

  10. 28 自定义View画坐标和柱状图

    自定义View类 RectView.java package com.qf.sxy.day29_customview.widget; import android.content.Context; i ...