在本文中,我列出瞭如何使用Go執行常見的SQL數據庫操作。
簡介database/sql
Go在其標準庫中提供了乾淨的SQL數據庫APIdatabase/sql
軟件包,但必須單獨安裝特定的數據庫驅動程序。
這是一種明智的方法,因為它提供了幾乎每個數據庫驅動程序都實現的通用接口。
如果要使用MySQL,可以使用https://github.com/go-sql-driver/mysql。
如果您使用的是PostgreSQL,請使用https://github.com/lib/pq。
您只需要使用以下內容包含libimport _
和database/sql
API將配置為啟用該驅動程序:
import "database/sql"
import _ "github.com/go-sql-driver/mysql"
打開數據庫連接
儘管目標是使其抽象化,但在某些方面仍然存在差異,例如在連接數據庫的方式上:
import "database/sql"
import _ "github.com/go-sql-driver/mysql"
//…
db, err := sql.Open(“mysql”, “theUser:[email protected]/theDbName”)
if err != nil {
panic(err)
}
import “database/sql”
import _ “github.com/lib/pq”
//…
db, err := sql.Open(“postgres”, “user=theUser dbname=theDbName sslmode=verify-full”)
if err != nil {
panic(err)
}
但是實際的大多數API都是與數據庫無關的,並且可以很容易地互換(這裡不談論SQL,僅指數據庫API)。
關閉數據庫連接
在有意義的地方,您應該始終關閉數據庫連接。
您可以照常使用defer
在打開數據庫連接的函數結束時將其關閉:
db, err := sql.Open("postgres", psqlInfo)
defer db.Close()
從數據庫中提取數據
選擇單行
查詢表分兩個步驟。首先你打電話db.QueryRow()
,然後您致電Scan()
結果。
例子:
id := 1
var col string
sqlStatement := `SELECT col FROM my_table WHERE id=$1`
row := db.QueryRow(sqlStatement, id)
err := row.Scan(&col)
if err != nil {
if err == sql.ErrNoRows {
fmt.Println("Zero rows found")
} else {
panic(err)
}
}
db.QueryRow()
用於查詢表中的單個值。
簽名:
func (db *DB) QueryRow(query string, args ...interface{}) *Row
它返回一個指向db.Row
價值。
(*Row) Scan
掃描行,將列值複製到傳遞給它的參數中。
簽名:
func (r *Row) Scan(dest ...interface{}) error
如果返回了多個行,則僅掃描第一行並忽略其餘部分。
如果未返回任何行,則返回一個ErrNoRows
錯誤。
var ErrNoRows = errors.New("sql: no rows in result set")
選擇多行
為了查詢單行,我們使用了db.QueryRow()
。要查詢多行,我們使用db.Query()
,它返回一個*Rows
價值。
從文檔中:
//Rows is the result of a query. Its cursor starts before the first row of the result set. Use Next to advance through the rows:
rows, err := db.Query("SELECT ...")
...
defer rows.Close()
for rows.Next() {
var id int
var name string
err = rows.Scan(&id, &name)
...
}
err = rows.Err() // get any error encountered ing iteration
...
// Err返回在迭代過程中遇到的錯誤(如果有)。 //可以在顯式或隱式的Close之後調用Err。
我們需要迭代rows.Next()
,這使我們可以致電rows.Scan()
進入循環。
如果在準備下一行時發生任何錯誤,則循環結束,我們可以通過調用來獲取錯誤rows.Err()
:
type Timeline struct {
Id int
Content string
}
rows, err := db.Query(`SELECT id, content FROM timeline`)
if err != nil {
panic(err)
}
defer rows.Close()
for rows.Next() {
timeline := Timeline{}
err = rows.Scan(&timeline.Id, &timeline.Content)
if err != nil {
panic(err)
}
fmt.Println(timeline)
}
err = rows.Err()
if err != nil {
panic(err)
}
更多教程:
- 使用NGINX反向代理服務Go服務
- 在Go中復制結構
- Go Web服務器的基礎
- 在Go中對地圖類型進行排序
- 簡而言之去指針
- 轉到標籤說明
- 開始日期和時間格式
- 使用Go進行JSON處理
- 可變參數函數
- 去弦備忘單
- 轉到空界面說明
- 使用VS Code和Delve調試Go
- 命名為Go返回參數
- 在Go中生成隨機數和字符串
- Go項目的文件系統結構
- Go中的二進制搜索算法
- 在Go中使用命令行標誌
- GOPATH解釋
- 使用Go構建一個命令行應用程序:lolcat
- 使用Go構建CLI命令:Cowsay
- 在Go中使用殼管
- Go CLI教程:財富克隆
- 使用Go列出文件夾中的文件
- 使用Go從GitHub獲取存儲庫列表
- 去,將一小段字符串附加到文件中
- 去,將字符串轉換為字節片
- 使用Go可視化您本地的Git貢獻
- Go CPU和內存分析入門
- 解決Go程序中的“不支持索引”錯誤
- 測量Go程序中的執行時間
- 使用Go構建Web爬網程序以檢測重複的標題
- 最佳實踐:指針還是價值接收者?
- 最佳實踐:您應該使用方法還是函數?
- Go數據結構:集
- 前往地圖備忘單
- 在Go中生成泛型類型的實現
- Go數據結構:字典
- Go數據結構:哈希表
- 在“通過通道”中實現事件偵聽器
- Go數據結構:堆棧
- Go數據結構:隊列
- Go數據結構:二進制搜索樹
- Go數據結構:圖形
- Go數據結構:鍊錶
- Go數據結構的完整指南
- 比較Go值
- Go是面向對象的嗎?
- 在Go中使用SQL數據庫
- 在Go中使用環境變量
- 上篇教程:PostgreSQL支持的REST API
- 在Go Web服務器上啟用CORS
- 在Docker容器中部署Go應用程序
- 為什麼Go是作為PHP開發人員學習的功能強大的語言
- 去,刪除io.Reader.ReadString換行符
- 開始,如何觀看更改並重建程序
- 去算一下自約會以來的月份
- 在Go中訪問HTTP POST參數