golang——database/sql包学习
1、database/sql包
sql包提供了保证SQL或类SQL数据库的泛用接口。
使用sql包时必须注入(至少)一个数据库驱动。
(1)获取mysql driver:go get -v github.com/go-sql-driver/mysql
(2)代码示例:
package main import (
"database/sql"
"fmt"
"log"
"time" _ "github.com/go-sql-driver/mysql"
) // 检查错误
func checkErr(err error) {
if err != nil {
log.Fatalln(err)
}
} // 事务错误
func checkTxErr(err error, tx *sql.Tx) {
if err != nil {
log.Println(err)
err = tx.Rollback()
checkErr(err)
}
} // 数据库实体
type User struct {
ID int
Name string
Age int
Sex int
AddDate time.Time
} func main() {
//1、获取数据库连接
db, err := sql.Open("mysql", "root:123456@tcp(127.0.0.1:3306)/test?parseTime=true")
checkErr(err)
defer db.Close()
fmt.Println("数据库连接成功")
//2、判断连接是否有效
err = db.Ping()
checkErr(err)
fmt.Println("数据库连接有效")
//3、创建表
sql := `
CREATE TABLE IF NOT EXISTS users(
id INT NOT NULL AUTO_INCREMENT,
name VARCHAR(100) NOT NULL,
age INT NOT NULL,
sex TINYINT,
add_date DATETIME,
PRIMARY KEY(id)
)
`
_, err = db.Exec(sql)
checkErr(err) //4、添加数据
// sql = "INSERT INTO users (name,age,sex,add_date) VALUES (?,?,?,?)"
// res, err := db.Exec(sql, "张三", 18, 1, time.Now())
// checkErr(err)
// fmt.Println(res.LastInsertId()) //5、查询数据
sql = "SELECT id,name,age,sex,add_date FROM users"
rows, err := db.Query(sql)
checkErr(err)
defer rows.Close()
user := User{}
for rows.Next() {
err = rows.Scan(&user.ID, &user.Name, &user.Age, &user.Sex, &user.AddDate)
checkErr(err)
fmt.Println(user, user.AddDate.Format("2006/01/02 15:04:05"))
}
err = rows.Err()
checkErr(err) //6、查询一行
sql = "SELECT id,name,age,sex,add_date FROM users"
row := db.QueryRow(sql)
err = row.Scan(&user.ID, &user.Name, &user.Age, &user.Sex, &user.AddDate)
checkErr(err)
fmt.Println(user) //7、命令
sql = "UPDATE users SET name=? WHERE id=?;"
stmt, err := db.Prepare(sql)
checkErr(err)
defer stmt.Close()
result, err := stmt.Exec("李四", 1)
checkErr(err)
fmt.Println(result.RowsAffected()) //8、查询
sql = "SELECT id,name,age,sex,add_date FROM users WHERE id=?"
stmt2, err := db.Prepare(sql)
checkErr(err)
defer stmt2.Close()
row = stmt2.QueryRow(1)
err = row.Scan(&user.ID, &user.Name, &user.Age, &user.Sex, &user.AddDate)
checkErr(err)
fmt.Println(user) //9、事务
tx, err := db.Begin()
checkErr(err)
_, err = tx.Exec("UPDATE users SET age=? WHERE id=?", 20, 1)
checkTxErr(err, tx)
_, err = tx.Exec("UPDATE users SET sex=? WHERE id=?", 1, 1)
checkTxErr(err, tx)
err = tx.Commit()
checkTxErr(err, tx) //10、查询一行
sql = "SELECT id,name,age,sex,add_date FROM users"
row = db.QueryRow(sql)
err = row.Scan(&user.ID, &user.Name, &user.Age, &user.Sex, &user.AddDate)
checkErr(err)
fmt.Println(user) }
2、数据库
2.1、type DB struct{}
DB是一个数据库句柄,代表一个具有零到多个底层连接的连接池。
它可以安全的被多个go程同时使用。
连接池的大小可以用SetMaxIdleConns方法控制。
2.2、常用方法
(1)func Open(driverName, dataSourceName string) (*DB, error)
打开数据库,返回数据库句柄,DB可以安全的被多个go程同时使用,并会维护自身的闲置连接池。
Open函数只需调用一次,很少需要关闭DB。
(2)func (db *DB) Driver() driver.Driver
返回数据库下层驱动。
(3)func (db *DB) Ping() error
检查与数据库的连接是否仍有效,如果需要会创建连接。
(4)func (db *DB) Close() error
关闭数据库,释放任何打开的资源。
一般不会关闭DB,因为DB句柄通常被多个go程共享,并长期活跃。
(5)func (db *DB) SetMaxOpenConns(n int)
设置与数据库建立连接的最大数目。
如果n大于0且小于最大闲置连接数,会将最大闲置连接数减小到匹配最大开启连接数的限制。
如果n <= 0,不会限制最大开启连接数,默认为0(无限制)。
(6)func (db *DB) SetMaxIdleConns(n int)
设置连接池中的最大闲置连接数。
如果n大于最大开启连接数,则新的最大闲置连接数会减小到匹配最大开启连接数的限制。
如果n <= 0,不会保留闲置连接。
(7)func (db *DB) Exec(query string, args ...interface{}) (Result, error)
执行一次命令(包括查询、删除、更新、插入等),不返回任何执行结果。
参数args表示query中的占位参数。
(8)func (db *DB) Query(query string, args ...interface{}) (*Rows, error)
执行一次查询,返回多行结果(即Rows),一般用于执行select命令。
(9)func (db *DB) QueryRow(query string, args ...interface{}) *Row
执行一次查询,并期望返回最多一行结果(即Row)。
总是返回非nil的值,直到返回值的Scan方法被调用时,才会返回被延迟的错误。
(10)func (db *DB) Prepare(query string) (*Stmt, error)
创建一个准备好的状态用于之后的查询和命令。
返回值可以同时执行多个查询和命令。
(11)func (db *DB) Begin() (*Tx, error)
开始一个事务。
隔离水平由数据库驱动决定。
3、数据表
3.1、type Rows{}
Rows是查询的结果。
它的游标指向结果集的第零行,使用Next方法来遍历各行结果。
3.2、常用方法
(1)func (rs *Rows) Columns() ([]string, error)
返回列名。
如果Rows已经关闭会返回错误。
(2)func (rs *Rows) Scan(dest ...interface{}) error
Scan将当前行各列结果填充进dest指定的各个值中。
如果某个参数的类型为*[]byte,Scan会保存对应数据的拷贝,该拷贝为调用者所有,可以安全的,修改或无限期的保存。
如果参数类型为*RawBytes可以避免拷贝;参见RawBytes的文档获取其使用的约束。
如果某个参数的类型为*interface{},Scan会不做转换的拷贝底层驱动提供的值。
如果值的类型为[]byte,会进行数据的拷贝,调用者可以安全使用该值。
(3)func (rs *Rows) Next() bool
Next准备用于Scan方法的下一行结果。
如果成功会返回真,如果没有下一行或者出现错误会返回假。
每一次调用Scan方法,甚至包括第一次调用该方法,都必须在前面先调用Next方法。
(4)func (rs *Rows) Close() error
关闭Rows,阻止对其更多的列举。
如果Next方法返回假,Rows会自动关闭。
检查Err方法结果的条件。
Close方法是幂等的(多次调用无效的成功),不影响Err方法的结果。
(5)func (rs *Rows) Err() error
Err返回可能的、在迭代时出现的错误。
Err需在显式或隐式调用Close方法后调用。
4、数据行
4.1、type Row{}
QueryRow方法返回Row,代表单行查询结果。
4.2、常用方法
(1)func (r *Row) Scan(dest ...interface{}) error
Scan将该行查询结果各列分别保存进dest参数指定的值中。
如果该查询匹配多行,Scan会使用第一行结果并丢弃其余各行。
如果没有匹配查询的行,Scan会返回ErrNoRows。
5、SQL命令状态
5.1、type Stmt struct{}
Stmt是准备好的状态。
Stmt可以安全的被多个go程同时使用。
5.2、常用方法
(1)func (s *Stmt) Exec(args ...interface{}) (Result, error)
使用提供的参数执行准备好的命令状态,返回Result类型的该状态执行结果的总结。
(2)func (s *Stmt) Query(args ...interface{}) (*Rows, error)
使用提供的参数执行准备好的查询状态,返回Rows类型查询结果。
(3)func (s *Stmt) QueryRow(args ...interface{}) *Row
使用提供的参数执行准备好的查询状态。
如果在执行时遇到了错误,该错误会被延迟,直到返回值的Scan方法被调用时才释放。
返回值总是非nil的。
如果没有查询到结果,*Row类型返回值的Scan方法会返回ErrNoRows;否则,Scan方法会扫描结果第一行并丢弃其余行。
(4)func (s *Stmt) Close() error
关闭状态。
6、事务
6.1、type Tx struct{}
Tx代表一个进行中的数据库事务。
一次事务必须以对Commit或Rollback的调用结束。
调用Commit或Rollback后,所有对事务的操作都会失败并返回错误值ErrTxDone。
6.2、常用方法
(1)func (tx *Tx) Exec(query string, args ...interface{}) (Result, error)
执行命令,但不返回结果。例如执行insert和update。
(2)func (tx *Tx) Query(query string, args ...interface{}) (*Rows, error)
执行查询并返回零到多行结果(Rows),一般执行select命令。
(3)func (tx *Tx) QueryRow(query string, args ...interface{}) *Row
执行查询并期望返回最多一行结果(Row)。
总是返回非nil的结果,查询失败的错误会延迟到在调用该结果的Scan方法时释放。
(4)func (tx *Tx) Prepare(query string) (*Stmt, error)
准备一个专用于该事务的状态。
返回的该事务专属状态操作在Tx递交会回滚后不能再使用。
(5)func (tx *Tx) Stmt(stmt *Stmt) *Stmt
使用已存在的状态生成一个该事务特定的状态。
(6)func (tx *Tx) Commit() error
提交事务。
(7)func (tx *Tx) Rollback() error
回滚事务。
golang——database/sql包学习的更多相关文章
- 在Golang中如何正确地使用database/sql包访问数据库
本文记录了我在实际工作中关于数据库操作上一些小经验,也是新手入门golang时我认为一定会碰到问题,没有什么高大上的东西,所以希望能抛砖引玉,也算是对这个问题的一次总结. 其实我也是一个新手,机缘巧合 ...
- 关于Golang中database/sql包的学习
go-sql-driver 请求一个连接的函数有好几种,执行完毕处理连接的方式稍有差别,大致如下: db.Ping() 调用完毕后会马上把连接返回给连接池. db.Exec() 调用完毕后会马上把连接 ...
- Golang中database/sql包
驱动 github.com/go-sql-driver/mysql 请求一个连接的函数有好几种,执行完毕处理连接的方式稍有差别,大致如下: db.Ping() 调用完毕后会马上把连接返回给连接池. d ...
- golang database sql DSN (Data Source Name)中的timeout, readTimeout
golang 语言,在打开mysql DB时,有时会用到timeout,readTimeout两个参数. 1.timeout 建立连接超时时间 例如, "30s", "0 ...
- golang中context包学习
摘要 go语言中goroutine之间的关联关系,缺乏维护,在erlang中有专门的机制来保障新开仟程的生命周期, 在go语言中,只能通过channel + select来实现,但不够直观,感觉很绕. ...
- golang——net/rpc包学习
1.rpc包 rpc包提供了通过网络或其他I/O连接对一个对象的导出方法的访问. 只有满足如下标准的方法才能用于远程访问,其余方法会被忽略: (1)方法是导出的(2)方法有两个参数,都是导出类型或内建 ...
- go-mysql: database/sql 接口适配
go-mysql已经支持golang database/sql接口,并通过https://github.com/bradfitz/go-sql-test测试用例. 现在go-mysql可以直接通过go ...
- go标准库的学习-database/sql
参考:https://studygolang.com/pkgdoc 导入方式: import "database/sql" sql包提供了保证SQL或类SQL数据库的泛用接口. 使 ...
- go标准库的学习-database/sql/driver
参考:https://studygolang.com/pkgdoc 1>导入方式: import "database/sql/driver" driver包定义了应被数据库驱 ...
随机推荐
- 九度oj 题目1077:最大序列和
题目1077:最大序列和 时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:6435 解决:1931 题目描述: 给出一个整数序列S,其中有N个数,定义其中一个非空连续子序列T中所有数的和为T ...
- 华中农业大学第四届程序设计大赛网络同步赛-1020: Arithmetic Sequence,题挺好的,考思路;
1020: Arithmetic Sequence Time Limit: 1 Sec Memory Limit: 128 MB Submit: ->打开链接<- Descriptio ...
- 2018 & 微信小程序
2018 & 微信小程序 Wafer2 快速开发 Demo 本仓库是最简版的 Wafer2 开发套件,建议配合腾讯云微信小程序开发者工具解决方案一起使用.适用于想要使用 Wafer SDK 开 ...
- CSU 1225 最长上升子序列并记录其个数
;j<i;j++){ if(h[i] > h[j]){ ) cnt[i]+=cnt[j]; ) len[i] = len[j] + , cnt[i] = cnt[j]; } //身高相同的 ...
- [luoguP1098] 字符串的展开(模拟)
传送门 一个模拟. 代码 #include <cstdio> #include <cstring> #include <iostream> #define iswo ...
- 3.2 符号表之二叉查找树BST
一.插入和查找 1.二叉查找树(Binary Search Tree)是一棵二叉树,并且每个结点都含有一个Comparable的键,保证每个结点的键都大于其左子树中任意结点的键而小于其右子树的任意结点 ...
- Linux下汇编语言学习笔记54 ---
这是17年暑假学习Linux汇编语言的笔记记录,参考书目为清华大学出版社 Jeff Duntemann著 梁晓辉译<汇编语言基于Linux环境>的书,喜欢看原版书的同学可以看<Ass ...
- Java并发包——使用新的方式创建线程
Java并发包——使用新的方式创建线程 摘要:本文主要学习了如何使用Java并发包中的类创建线程. 部分内容来自以下博客: https://www.cnblogs.com/dolphin0520/p/ ...
- Spring Boot多数据源连接8小时后断开的问题解决(MySQL)
这个问题涉及的方面很多,需要一步步去排查,可能环境有问题,数据库有问题,但是网上最多的应该是如下的方式去解决. 以单个数据源为主,多个数据源基本方法一致. 1.MySQL 5版本之前可以通过在URL后 ...
- 怎样载入指定路径的Logback.xml
今天想外置logback.xml,谢了例如以下代码 File logbackFile = new File("./conf/logback.xml"); if (logbackFi ...