sql包提供了保证SQL或类SQL数据库的泛用接口。mysql
使用sql包时必须注入(至少)一个数据库驱动。git
(1)获取mysql driver:go get -v github.com/go-sql-driver/mysqlgithub
(2)代码示例:sql
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() { //一、获取数据库链接 db, err := sql.Open("mysql", "root:123456@tcp(127.0.0.1:3306)/test?parseTime=true") checkErr(err) defer db.Close() fmt.Println("数据库链接成功") //二、判断链接是否有效 err = db.Ping() checkErr(err) fmt.Println("数据库链接有效") //三、建立表 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) //四、添加数据 // 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()) //五、查询数据 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) //六、查询一行 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) //七、命令 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()) //八、查询 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) //九、事务 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) //十、查询一行 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.一、type DB struct{}数据库
DB是一个数据库句柄,表明一个具备零到多个底层链接的链接池。安全
它能够安全的被多个go程同时使用。tcp
链接池的大小能够用SetMaxIdleConns方法控制。函数
2.二、经常使用方法spa
(1)func Open(driverName, dataSourceName string) (*DB, error)orm
打开数据库,返回数据库句柄,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.一、type Rows{}
Rows是查询的结果。
它的游标指向结果集的第零行,使用Next方法来遍历各行结果。
3.二、经常使用方法
(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.一、type Row{}
QueryRow方法返回Row,表明单行查询结果。
4.二、经常使用方法
(1)func (r *Row) Scan(dest ...interface{}) error
Scan将该行查询结果各列分别保存进dest参数指定的值中。
若是该查询匹配多行,Scan会使用第一行结果并丢弃其他各行。
若是没有匹配查询的行,Scan会返回ErrNoRows。
5.一、type Stmt struct{}
Stmt是准备好的状态。
Stmt能够安全的被多个go程同时使用。
5.二、经常使用方法
(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.一、type Tx struct{}
Tx表明一个进行中的数据库事务。
一次事务必须以对Commit或Rollback的调用结束。
调用Commit或Rollback后,全部对事务的操做都会失败并返回错误值ErrTxDone。
6.二、经常使用方法
(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
回滚事务。