go-sql-driver

请求一个连接的函数有好几种,执行完毕处理连接的方式稍有差别,大致如下:

  • db.Ping() 调用完毕后会马上把连接返回给连接池。

  • db.Exec() 调用完毕后会马上把连接返回给连接池,但是它返回的Result对象还保留这连接的引用,当后面的代码需要处理结果集的时候连接将会被重用。

  • db.Query() 调用完毕后会将连接传递给sql.Rows类型,当然后者迭代完毕或者显示的调用.Clonse()方法后,连接将会被释放回到连接池。

  • db.QueryRow()调用完毕后会将连接传递给sql.Row类型,当.Scan()方法调用之后把连接释放回到连接池。

  • db.Begin() 调用完毕后将连接传递给sql.Tx类型对象,当.Commit()或.Rollback()方法调用后释放连接。

    连接DB

    sql.Open的第一个参数是driver名称,第二个参数是driver连接数据库的信息,各个driver可能不同。DB不是连接,并且只有当需要使用时才会创建连接,如果想立即验证连接,需要用Ping()方法,如下:

    err = db.Ping()if err != nil {
       // do something here
    }

    sql.DB的设计就是用来作为长连接使用的。不要频繁Open, Close。比较好的做法是,为每个不同的datastore建一个DB对象,保持这些对象Open。如果需要短连接,那么把DB作为参数传入function,而不要在function中Open, Close。

    读取DB

    如果方法包含Query,那么这个方法是用于查询并返回rows的。其他情况应该用Exec()

    var (
       id int
       name string
    )
    rows, err := db.Query("select id, name from users where id = ?", 1)if err != nil {
       log.Fatal(err)
    }
    defer rows.Close()for rows.Next() {
       err := rows.Scan(&id, &name)
       if err != nil {
           log.Fatal(err)
       }
       log.Println(id, name)
    }
    err = rows.Err()if err != nil {
       log.Fatal(err)
    }

    上面代码的过程为:db.Query()表示向数据库发送一个query,defer rows.Close()非常重要,遍历rows使用rows.Next(), 把遍历到的数据存入变量使用rows.Scan(), 遍历完成后检查error。有几点需要注意:

    1. 检查遍历是否有error

    2. 结果集(rows)未关闭前,底层的连接处于繁忙状态。当遍历读到最后一条记录时,会发生一个内部EOF错误,自动调用rows.Close(),但是如果提前退出循环,rows不会关闭,连接不会回到连接池中,连接也不会关闭。所以手动关闭非常重要。rows.Close()可以多次调用,是无害操作。

    单行Query

    err在Scan后才产生,所以可以如下写:

    var name stringerr = db.QueryRow("select name from users where id = ?", 1).Scan(&name)if err != nil {
       log.Fatal(err)
    }
    fmt.Println(name)

    修改数据,事务

    一般用Prepare()和Exec()完成INSERTUPDATEDELETE操作。

    事务

    db.Begin()开始事务,Commit() 或 Rollback()关闭事务。Tx从连接池中取出一个连接,在关闭之前都是使用这个连接。Tx不能和DB层的BEGINCOMMIT混合使用。

    如果你需要通过多条语句修改连接状态,你必须使用Tx,例如:

    • 创建仅对单个连接可见的临时表

    • 设置变量,例如SET @var := somevalue

    • 改变连接选项,例如字符集,超时

    处理Error

    循环Rows的Error

    如果循环中发生错误会自动运行rows.Close(),用rows.Err()接收这个错误,Close方法可以多次调用。循环之后判断error是非常必要的。

    关闭Resultsets时的error

    如果你在rows遍历结束之前退出循环,必须手动关闭

关于连接池

  1. 当需要连接,且连接池中没有可用连接时,新的连接就会被创建。

  2. 默认没有连接上限,这可能会导致数据库产生错误“too many connections”

  3. db.SetMaxIdleConns(N)设置最大空闲连接数

  4. db.SetMaxOpenConns(N)设置最大打开连接数

  5. 长时间保持空闲连接可能会导致db timeout

关于Golang中database/sql包的学习的更多相关文章

  1. Golang中database/sql包

    驱动 github.com/go-sql-driver/mysql 请求一个连接的函数有好几种,执行完毕处理连接的方式稍有差别,大致如下: db.Ping() 调用完毕后会马上把连接返回给连接池. d ...

  2. 在Golang中如何正确地使用database/sql包访问数据库

    本文记录了我在实际工作中关于数据库操作上一些小经验,也是新手入门golang时我认为一定会碰到问题,没有什么高大上的东西,所以希望能抛砖引玉,也算是对这个问题的一次总结. 其实我也是一个新手,机缘巧合 ...

  3. golang——database/sql包学习

    1.database/sql包 sql包提供了保证SQL或类SQL数据库的泛用接口. 使用sql包时必须注入(至少)一个数据库驱动. (1)获取mysql driver:go get -v githu ...

  4. golang中的reflect包用法

    最近在写一个自动生成api文档的功能,用到了reflect包来给结构体赋值,给空数组新增一个元素,这样只要定义一个input结构体和一个output的结构体,并填写一些相关tag信息,就能使用程序来生 ...

  5. golang中container/heap包源码分析

    学习golang难免需要分析源码包中一些实现,下面就来说说container/heap包的源码 heap的实现使用到了小根堆,下面先对堆做个简单说明 1. 堆概念 堆是一种经过排序的完全二叉树,其中任 ...

  6. golang中container/list包源码分析

    golang源码包中container/list实际上是一个双向链表 提供链表的一些基本操作,下面就结合定义和接口进行下说明 1. 定义 // Element is an element of a l ...

  7. golang中的rpc包用法

    RPC,即 Remote Procedure Call(远程过程调用),说得通俗一点就是:调用远程计算机上的服务,就像调用本地服务一样. 我所在公司的项目是采用基于Restful的微服务架构,随着微服 ...

  8. golang中的context包

    标准库的context包 从设计角度上来讲, golang的context包提供了一种父routine对子routine的管理功能. 我的这种理解虽然和网上各种文章中讲的不太一样, 但我认为基本上还是 ...

  9. golang中net/http包的简单使用

    一.介绍 http包提供了http客户端和服务端的实现 Get,Head,Post和PostForm函数发出http.https的请求 程序在使用完回复后必须关闭回复的主体 #简单的访问网站,由于没有 ...

随机推荐

  1. 浅谈Cookie、Session与Cache的区别

    以前实现数据的缓存有多种方法,如客户端的Cookie,服务器端的Session.Application. 一.Cookie Cookie是保存客户端的一组数据,主要用来保存用户的个人信息,主要存放浏览 ...

  2. Java Web整合开发王者归来(JSP + Servlet + Struts + Hibernate + Spring) - 读书笔记

    第1章 状态码表示响应类型: 保留 表示请求成功地接收 完成请求客户需进一步细化请求 客户错误 服务器错误 Web服务器: Apache服务器,特长是处理静态页面,效率非常高. Tomcat提供对JS ...

  3. [js高手之路]Node.js模板引擎教程-jade速学与实战1-基本用法

    环境准备: 全局安装jade: npm install jade -g 初始化项目package.json: npm init --yes 安装完成之后,可以使用 jade --help 查看jade ...

  4. vue生命周期理解

    https://segmentfault.com/a/1190000008010666?utm_source=tag-newest

  5. p2p项目工具类

    1.用于存放当前用户的上下文UserContext package com.xmg.p2p.base.util; import javax.servlet.http.HttpSession; impo ...

  6. Burp Suite插件推荐

    BurpSuiteHTTPSmuggler 网址 https://github.com/nccgroup/BurpSuiteHTTPSmuggler 作用 利用 中间件对 HTTP 协议的实现的特性 ...

  7. 重装系统,打开VS进行程序调试运行的时候 Unable to find manifest signing certificate in the certificate store

    重装系统,打开VS进行程序调试运行的时候 Unable to find manifest signing certificate in the certificate store. 项目的属性-> ...

  8. leetCode题解之旋转数字

    1.题目描述 X is a good number if after rotating each digit individually by 180 degrees, we get a valid n ...

  9. python文本文件处理和用户输入

    #用户输入 a = input('please input: ') #这个输入什么即是什么,比如输入1,则a变量=1,输入'abc',则a变量 = 'abc',输入abc则报错,因为会把abc当做一个 ...

  10. 全自动LTI部署OS

    全自动LTI部署OS:零.通过ADK制作WinPE(需包含有imagex.exe工具,用来捕获映像)一.使用WinPE中的imagex捕获映像(install.wim)二.使用MDT制作启动映像(bo ...