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
回滾事務。