Go語言中mysql資料庫操作(一)
資料的持久化是程式中必不可少的,所以程式語言中對資料庫的操作是非常重要的一塊,本文介紹Go語言對mysql資料庫的操作。
基本操作
建立連線
db, err := sql.Open("mysql", "root:root@tcp(127.0.0.1:3306)/betting?charset=utf8")
errDeal("連線資料庫", err)
defer db.Close()
連線引數一般有以下幾種
user@unix(/path/to/socket)/dbname?charset=utf8
user:password@tcp(localhost:5555)/dbname?charset=utf8
user:password@/dbname
user:password@tcp([de:ad:be:ef::ca:fe]:80)/dbname
增刪改操作
// 插入資料---------------------方法1
result, err := db.Exec("INSERT INTO admin_log(admin_username,log_time,log_ip,log_type,log_desc)" +
" VALUES(?,now(),?,?,?)", "admin", "127.0.0.1", "登入", "登入成功")
errDeal("插入資料", err)
// 檢視返回資訊
count, err := result.RowsAffected()
errDeal("檢視插入資料條數", err)
fmt.Printf("插入資料條數:%dn", count)
id, err := result.LastInsertId()
errDeal("檢視最後插入資料的id", err)
fmt.Printf("最後插入資料的id:%dn", id)
// 插入資料---------------------方法2,先建立一個預處理語句,再執行
stmt, err := db.Prepare("INSERT INTO admin_log(admin_username,log_time,log_ip,log_type,log_desc)" +
" VALUES(?,now(),?,?,?)")
result1, err1 := stmt.Exec("admin", "127.0.0.1", "登入", "登入成功")
errDeal("方法2插入資料", err1)
fmt.Println(result1.LastInsertId())
// 刪除資料
result2, err := db.Exec("DELETE FROM admin_log WHERE id=?", 2014)
fmt.Println(result2.RowsAffected())
// 更新資料
result3, err := db.Exec("UPDATE admin_log SET log_ip=? WHERE id=?", "192.168.8.9", 2017)
fmt.Println(result3.RowsAffected())
單條資料查詢
// 先定義儲存查詢結果的變數
var rid int
var username, time, ip, logType string
var desc, remark, spare interface{} // 如果欄位中可能出現值為nil的情況,可以將變數申明為interface{}型別
err2 := db.QueryRow("SELECT id,admin_username,log_time,log_ip,log_type,log_desc,remark,spare" +
" FROM admin_log WHERE id=?", 2017).Scan(&rid, &username, &time, &ip, &logType, &desc, &remark, &spare) // 傳入的是變數的指標
errDeal("查詢單條資料", err2)
fmt.Printf("id=%d,username=%s,time=%s,ip=%s,logType=%s,desc=%s,remark=%v,spare=%vn", rid, username, time, ip, logType, desc, remark, spare)
多條資料查詢
// 查詢多條資料
rows, err3 := db.Query("SELECT admin_username,log_time,log_ip,log_type,log_desc" +
" FROM admin_log WHERE id=? OR id=?", 2017, 2019)
errDeal("查詢多條資料", err3)
// 對多條資料進行遍歷
for rows.Next() {
err4 := rows.Scan(&username, &time, &ip, &logType, &desc)
errDeal("遍歷多條資料", err4)
fmt.Printf("username=%s,time=%s,ip=%s,logType=%s,desc=%sn", username, time, ip, logType, desc)
}
// 如果查詢中不指定具體欄位,使用*
rows, err33 := db.Query("SELECT *" +
" FROM admin_log WHERE id>?", 2017)
errDeal("查詢多條資料", err33)
// 查詢所有欄位名,返回string切片
columes, err333 := rows.Columns()
errDeal("rows.Columns()方法呼叫", err333)
fmt.Printf("%T----%vn", columes, columes)
var scanColumes = make([]interface{}, len(columes))
var values = make([]interface{}, len(columes))
for index, _ := range scanColumes {
scanColumes[index] = &values[index]
}
for rows.Next() {
err4 := rows.Scan(scanColumes...)
errDeal("遍歷多條資料", err4)
for i, val := range values {
if strings.EqualFold(judgeType(val), "[]uint8") {
fmt.Printf("%s(%T)==%st", columes[i], val, val)
} else {
fmt.Printf("%s(%T)==%vt", columes[i], val, val)
}
}
fmt.Println()
}
事務
開啟事務
// 開啟事務,tx是從連線池中取出一個連線,在關閉之前都是使用這個連線,提交事務和回滾事務都是操作tx
tx, err5 := db.Begin()
errDeal("開啟事務", err5)
_, err6 := tx.Exec("UPDATE admin_log SET log_desc=? WHERE id=?", "測試事務222", 2019)
//if err6 != nil {
if err6 == nil {
tx.Rollback() // 回滾
}
tx.Commit() // 提交
批次插入資料
// 批次資料插入
tx, err7 := db.Begin()
errDeal("資料批次插入,開啟事務", err7)
insertValues := [][]interface{}{{"admin", "127.0.0.1", "登入", "登入成功"},{"admin", "127.0.0.1", "刪除", "刪除資料"},{"admin", "127.0.0.1", "退出", "退出系統"}}
stmt, err8 := tx.Prepare("INSERT INTO admin_log(admin_username,log_time,log_ip,log_type,log_desc) VALUES(?,now(),?,?,?)")
errDeal("資料批次插入,預處理", err8)
for _, val := range insertValues {
_, err := stmt.Exec(val...)
if err != nil {
fmt.Printf("出現錯誤回滾,錯誤資訊:%v", err)
tx.Rollback()
}
}
tx.Commit()
sqlx的使用及批次插入
xdb, err9 := sqlx.Open("mysql", "root:root@tcp(127.0.0.1:3306)/betting?charset=utf8")
errDeal("sqlx連線資料庫", err9)
txx, err10 := xdb.Beginx()
errDeal("sqlx開啟事務", err10)
insertValuesx := [][]interface{}{{"admin", "127.0.0.1", "登入", "登入成功X"},{"admin", "127.0.0.1", "刪除", "刪除資料X"},{"admin", "127.0.0.1", "退出", "退出系統X"}}
stmtx, err11 := txx.Preparex("INSERT INTO admin_log(admin_username,log_time,log_ip,log_type,log_desc) VALUES(?,now(),?,?,?)")
errDeal("資料批次插入,預處理", err11)
for _, val := range insertValuesx {
_, err := stmtx.Exec(val...)
if err != nil {
fmt.Printf("sqlx出現錯誤回滾,錯誤資訊:%v", err)
txx.Rollback()
}
}
txx.Commit()
完整程式碼
package main
import (
"database/sql"
_"github.com/go-sql-driver/mysql" // 這裡很重要,匯入自己本地使用的資料庫驅動,前面是下劃線,否則會報錯:sql: unknown driver "mysql" (forgotten import?)
"fmt"
"strings"
"github.com/jmoiron/sqlx"
)
func main() {
// 連線資料庫,使用者名稱:密碼@協議(地址:埠)/資料庫?引數=引數值,常用"使用者名稱:密碼@tcp(ip:埠)/資料庫名?charset=字符集"
db, err := sql.Open("mysql", "root:root@tcp(127.0.0.1:3306)/betting?charset=utf8")
errDeal("連線資料庫", err)
defer db.Close()
//=========================================================================================增刪改
// 插入資料---------------------方法1
result, err := db.Exec("INSERT INTO admin_log(admin_username,log_time,log_ip,log_type,log_desc)" +
" VALUES(?,now(),?,?,?)", "admin", "127.0.0.1", "登入", "登入成功")
errDeal("插入資料", err)
// 檢視返回資訊
count, err := result.RowsAffected()
errDeal("檢視插入資料條數", err)
fmt.Printf("插入資料條數:%dn", count)
id, err := result.LastInsertId()
errDeal("檢視最後插入資料的id", err)
fmt.Printf("最後插入資料的id:%dn", id)
// 插入資料---------------------方法2,先建立一個預處理語句,再執行
stmt, err := db.Prepare("INSERT INTO admin_log(admin_username,log_time,log_ip,log_type,log_desc)" +
" VALUES(?,now(),?,?,?)")
result1, err1 := stmt.Exec("admin", "127.0.0.1", "登入", "登入成功")
errDeal("方法2插入資料", err1)
fmt.Println(result1.LastInsertId())
// 刪除資料
result2, err := db.Exec("DELETE FROM admin_log WHERE id=?", 2014)
fmt.Println(result2.RowsAffected())
// 更新資料
result3, err := db.Exec("UPDATE admin_log SET log_ip=? WHERE id=?", "192.168.8.9", 2017)
fmt.Println(result3.RowsAffected())
//=============================================================================================查詢
// 查詢單條資料
// 先定義儲存查詢結果的變數
var rid int
var username, time, ip, logType string
var desc, remark, spare interface{} // 如果欄位中可能出現值為nil的情況,可以將變數申明為interface{}型別
err2 := db.QueryRow("SELECT id,admin_username,log_time,log_ip,log_type,log_desc,remark,spare" +
" FROM admin_log WHERE id=?", 2017).Scan(&rid, &username, &time, &ip, &logType, &desc, &remark, &spare) // 傳入的是變數的指標
errDeal("查詢單條資料", err2)
fmt.Printf("id=%d,username=%s,time=%s,ip=%s,logType=%s,desc=%s,remark=%v,spare=%vn", rid, username, time, ip, logType, desc, remark, spare)
// 查詢多條資料
rows, err3 := db.Query("SELECT admin_username,log_time,log_ip,log_type,log_desc" +
" FROM admin_log WHERE id=? OR id=?", 2017, 2019)
errDeal("查詢多條資料", err3)
// 對多條資料進行遍歷
for rows.Next() {
err4 := rows.Scan(&username, &time, &ip, &logType, &desc)
errDeal("遍歷多條資料", err4)
fmt.Printf("username=%s,time=%s,ip=%s,logType=%s,desc=%sn", username, time, ip, logType, desc)
}
// 如果查詢中不指定具體欄位,使用*
rows, err33 := db.Query("SELECT *" +
" FROM admin_log WHERE id>?", 2017)
errDeal("查詢多條資料", err33)
// 查詢所有欄位名,返回string切片
columes, err333 := rows.Columns()
errDeal("rows.Columns()方法呼叫", err333)
fmt.Printf("%T----%vn", columes, columes)
var scanColumes = make([]interface{}, len(columes))
var values = make([]interface{}, len(columes))
for index, _ := range scanColumes {
scanColumes[index] = &values[index]
}
for rows.Next() {
err4 := rows.Scan(scanColumes...)
errDeal("遍歷多條資料", err4)
for i, val := range values {
if strings.EqualFold(checkType(val), "[]uint8") {
fmt.Printf("%s(%T)==%st", columes[i], val, val)
} else {
fmt.Printf("%s(%T)==%vt", columes[i], val, val)
}
}
fmt.Println()
}
// ==================================================================================================事務
// 開啟事務,tx是從連線池中取出一個連線,在關閉之前都是使用這個連線,提交事務和回滾事務都是操作tx
tx, err5 := db.Begin()
errDeal("開啟事務", err5)
_, err6 := tx.Exec("UPDATE admin_log SET log_desc=? WHERE id=?", "測試事務222", 2019)
//if err6 != nil {
if err6 == nil {
tx.Rollback() // 回滾
}
tx.Commit() // 提交
// 批次資料插入
tx, err7 := db.Begin()
errDeal("資料批次插入,開啟事務", err7)
insertValues := [][]interface{}{{"admin", "127.0.0.1", "登入", "登入成功"},{"admin", "127.0.0.1", "刪除", "刪除資料"},{"admin", "127.0.0.1", "退出", "退出系統"}}
stmt, err8 := tx.Prepare("INSERT INTO admin_log(admin_username,log_time,log_ip,log_type,log_desc) VALUES(?,now(),?,?,?)")
errDeal("資料批次插入,預處理", err8)
defer stmt.Close()
// 透過迴圈將每條SQL的引數寫到目標表緩衝區。
for _, val := range insertValues {
_, err := stmt.Exec(val...)
if err != nil {
fmt.Printf("出現錯誤回滾,錯誤資訊:%v", err)
tx.Rollback()
}
}
tx.Commit()
// 使用sqlx批次資料插入
xdb, err9 := sqlx.Open("mysql", "root:root@tcp(127.0.0.1:3306)/betting?charset=utf8")
errDeal("sqlx連線資料庫", err9)
defer xdb.close()
txx, err10 := xdb.Beginx()
errDeal("sqlx開啟事務", err10)
insertValuesx := [][]interface{}{{"admin", "127.0.0.1", "登入", "登入成功X"},{"admin", "127.0.0.1", "刪除", "刪除資料X"},{"admin", "127.0.0.1", "退出", "退出系統X"}}
stmtx, err11 := txx.Preparex("INSERT INTO admin_log(admin_username,log_time,log_ip,log_type,log_desc) VALUES(?,now(),?,?,?)")
errDeal("資料批次插入,預處理", err11)
defer stmtx.Close()
// 透過迴圈將每條SQL的引數寫到目標表緩衝區。
for _, val := range insertValuesx {
_, err := stmtx.Exec(val...)
if err != nil {
fmt.Printf("sqlx出現錯誤回滾,錯誤資訊:%v", err)
txx.Rollback()
}
}
txx.Commit()
}
func errDeal(info string, err error) {
if err != nil {
panic(fmt.Sprintf("%s,錯誤資訊:%v", info, err))
}
}
func checkType(val interface{}) string {
switch val.(type) {
case []uint8 :
return "[]uint8"
}
return ""
}
©著作權歸作者所有:來自51CTO部落格作者thao888的原創作品,如需轉載,請註明出處,否則將追究法律責任
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/964/viewspace-2819604/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Go之資料庫操作Go資料庫
- MySQL(一) 資料表資料庫的基本操作MySql資料庫
- MySQL 資料庫操作MySql資料庫
- Flowmatic:Go語言中結構化併發庫Go
- Go 語言操作 MySQL 之 CURD 操作GoMySql
- Go 語言中的方法Go
- Go語言中的InterfaceGo
- Go語言中defer的一些坑Go
- 資料庫操作語句資料庫
- Mysql資料庫操作命令MySql資料庫
- PHP操作MySQL資料庫PHPMySql資料庫
- MySQL資料庫常用操作MySql資料庫
- 【Java】操作mysql資料庫JavaMySql資料庫
- MySQL資料庫基本操作MySql資料庫
- shell 操作mysql資料庫MySql資料庫
- 【MYSQL資料庫開發之二】MYSQL基礎語句的書寫與一些資料庫操作(建立使用資料庫、表)!MySql資料庫
- Go 語言操作 MySQL 之 事務操作GoMySql
- sql語言中join操作SQL
- 【Mysql】改資料庫庫名操作MySql資料庫
- 【Go學習筆記2】go語言中的基本資料型別和包的介紹(一)Go筆記資料型別
- Go 語言中的 collect 使用Go
- Go 語言中的外掛Go
- Go 語言中的 切片 --sliceGo
- 資料庫操作語言DDL資料庫
- 資料庫基本操作 術語資料庫
- mysql資料庫基本操作(六)MySql資料庫
- mysql資料庫基本操作(三)MySql資料庫
- mysql資料庫基本操作(四)MySql資料庫
- mysql資料庫基本操作(五)MySql資料庫
- 02、MySQL—資料庫基本操作MySql資料庫
- python資料庫(mysql)操作Python資料庫MySql
- python 操作mysql資料庫PythonMySql資料庫
- Python Mysql 資料庫操作PythonMySql資料庫
- python操作mysql資料庫PythonMySql資料庫
- 使用OTL操作MySQL資料庫MySql資料庫
- go 語言位操作庫 bitsetGo
- MySQL資料庫6:Go與MySQL事務MySql資料庫Go
- Go 語言操作 MySQL 之 SQLX 包GoMySql