关于Golang中database/sql包的学习
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。有几点需要注意:检查遍历是否有error
结果集(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()完成INSERT,UPDATE,DELETE操作。事务
db.Begin()开始事务,Commit()或Rollback()关闭事务。Tx从连接池中取出一个连接,在关闭之前都是使用这个连接。Tx不能和DB层的BEGIN,COMMIT混合使用。如果你需要通过多条语句修改连接状态,你必须使用Tx,例如:
创建仅对单个连接可见的临时表
设置变量,例如
SET @var := somevalue改变连接选项,例如字符集,超时
处理Error
循环Rows的Error
如果循环中发生错误会自动运行
rows.Close(),用rows.Err()接收这个错误,Close方法可以多次调用。循环之后判断error是非常必要的。关闭Resultsets时的error
如果你在rows遍历结束之前退出循环,必须手动关闭
关于连接池
当需要连接,且连接池中没有可用连接时,新的连接就会被创建。
默认没有连接上限,这可能会导致数据库产生错误“too many connections”
db.SetMaxIdleConns(N)设置最大空闲连接数db.SetMaxOpenConns(N)设置最大打开连接数长时间保持空闲连接可能会导致db timeout
关于Golang中database/sql包的学习的更多相关文章
- Golang中database/sql包
驱动 github.com/go-sql-driver/mysql 请求一个连接的函数有好几种,执行完毕处理连接的方式稍有差别,大致如下: db.Ping() 调用完毕后会马上把连接返回给连接池. d ...
- 在Golang中如何正确地使用database/sql包访问数据库
本文记录了我在实际工作中关于数据库操作上一些小经验,也是新手入门golang时我认为一定会碰到问题,没有什么高大上的东西,所以希望能抛砖引玉,也算是对这个问题的一次总结. 其实我也是一个新手,机缘巧合 ...
- golang——database/sql包学习
1.database/sql包 sql包提供了保证SQL或类SQL数据库的泛用接口. 使用sql包时必须注入(至少)一个数据库驱动. (1)获取mysql driver:go get -v githu ...
- golang中的reflect包用法
最近在写一个自动生成api文档的功能,用到了reflect包来给结构体赋值,给空数组新增一个元素,这样只要定义一个input结构体和一个output的结构体,并填写一些相关tag信息,就能使用程序来生 ...
- golang中container/heap包源码分析
学习golang难免需要分析源码包中一些实现,下面就来说说container/heap包的源码 heap的实现使用到了小根堆,下面先对堆做个简单说明 1. 堆概念 堆是一种经过排序的完全二叉树,其中任 ...
- golang中container/list包源码分析
golang源码包中container/list实际上是一个双向链表 提供链表的一些基本操作,下面就结合定义和接口进行下说明 1. 定义 // Element is an element of a l ...
- golang中的rpc包用法
RPC,即 Remote Procedure Call(远程过程调用),说得通俗一点就是:调用远程计算机上的服务,就像调用本地服务一样. 我所在公司的项目是采用基于Restful的微服务架构,随着微服 ...
- golang中的context包
标准库的context包 从设计角度上来讲, golang的context包提供了一种父routine对子routine的管理功能. 我的这种理解虽然和网上各种文章中讲的不太一样, 但我认为基本上还是 ...
- golang中net/http包的简单使用
一.介绍 http包提供了http客户端和服务端的实现 Get,Head,Post和PostForm函数发出http.https的请求 程序在使用完回复后必须关闭回复的主体 #简单的访问网站,由于没有 ...
随机推荐
- 谷歌旗下专业图片编辑Snapseed获重大更新
谷歌旗下的图片编辑应用Snapseed今天获得重大更新,承诺为用户的手机或者平板带来“精确和卓越控制的专业图片编辑软件”.Android和iOS版本同时获得更新,新增包括镜头模糊.色条对比.更加灵活的 ...
- VMWare开启DHCP和NAT服务(VMWare无法通过NAT上网以及和host主机通信的问题解决)
最近在学习Hadoop,开始做一个集群.由于各个节点的IP地址需要保持不变,我决定在VMWare采用NAT的模式联网. 但是在安装Ubuntu系统的时候,提示我DHCP服务未开启. Your netw ...
- 骆驼拼写法(CamelCase)
在英语中,依靠单词的大小写拼写复合词的做法,叫做"骆驼拼写法"(CamelCase).比如,backColor这个复合词,color的第一个字母采用大写. 这种拼写法在正规的英语中 ...
- HNCU专题训练_线段树(1)
1.内存控制2.敌兵布阵4.广告牌5.区间第k大数(模板题)6.just a Hook7.I Hate It8.动态的最长递增子序列(区间更新题)9.图灵树10.覆盖的面积14.买票问题16.村庄问题 ...
- JSP学习笔记(3)-JSP内置对象
有些对象不用声明就可以在JSP页面的Java程序片和表达式部分使用,这些对象就是JSP的内置对象. JSP常用的内置对象有request,response,session,application,o ...
- 不要在对抽象类接口abstract virtual什么的混淆不清了
(最近带一个新手入门 讲这边老费力了.) 接口和抽象类不过都是类的抽象罢了,这是他们的本质,只不过人们的思维角度不同而已,一个偏向为行为契约上的抽象(接口) 一个更像大自然中的繁衍关系(抽象类). 直 ...
- 总结oninput、onchange与onpropertychange事件的使用方法和差别
onchange事件仅仅在键盘或者鼠标操作改变对象属性,且失去焦点时触发,脚本触发无效:而onkeydown/onkeypress/onkeyup在处理复制.粘贴.拖拽.长按键(按住键盘不放)等细节上 ...
- 关于CSS重要知识点(1)
1. 盒子模型 CSS处理网页内容时,会把每一个元素"放在"一个盒子里,也就是所谓的盒子模型. 盒子模型包括4部分:内容,内边距(padding),边框(border)和外边距(m ...
- css绘制进度条,持续转动的进度条
//只有 progress pregress-par bar,进度条不会转, //增加 active 这个类,进度条会转, //html结构 <div class='progress activ ...
- drupal7 判断用户是否具有某个权限
user_access() 具体用法可参考http://www.drupalla.com/node/857