中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》
  • 首頁 > 
  • 教程 > 
  • 數據庫 > 
  • 如何理解Golang牽手PostgreSQL增刪改查+不寫結構快速掃描字段

如何理解Golang牽手PostgreSQL增刪改查+不寫結構快速掃描字段

發布時間:2021-10-22 10:50:20 來源:億速云 閱讀:146 作者:iii 欄目:數據庫

本篇內容介紹了“如何理解Golang牽手PostgreSQL增刪改查+不寫結構快速掃描字段”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

驅動安裝

執行以下命令安裝postgresql驅動

go get github.com/lib/pq

pq包支持的功能

  • SSL

  • 作為驅動程序, 與database/sql結合處理連接相關操作

  • 掃描時間time.Time類型, 如 timestamp[tz], time[tz], date

  • 掃描二進制blobs對象(Blob是內存中的數據緩沖, 用來匹配strign類型的ID和字節切片), 如: bytea

  • PostgreSQL的hstore數據類型支持

  • 支持COPY FROM

  • pq.ParseURL方法用來將urls轉化為sql.Open的連接字符串

  • 支持許多libpq庫兼容的環境變量

  • 支持Unix socket

  • 支持通知Notifications, 如:LISTEN/NOTIFY

  • 支持pgpass

  • GSS (Kerberos) 認證

連接字符串參數

pq包與libpq類似(libpq是用C編寫的底層接口,  為其他高級語言比如C++,Perl,Python,Tcl和ECPG等提供底層PostgreSQL支持). 建立連接時需要提供連接參數,  一部分支持libpq的參數也支持pq, 額外的, pq允許在連接字符串中指定運行時參數(如:search_path或work_mem),  libpq則不能在連接字符串中指定運行時參數, 只能在option參數中指定.

pq包為了兼容libpq包, 下面的連接參數都支持

* dbname - 需要連接的數據庫名 * user - 需要使用的用戶名 * password - 該用戶的密碼 * host - 需要連接的postgresql主機, unix域名套接字以/開始, 默認是localhost * port - postgresql綁定的端口 (默認5432) * sslmode - 是否使用SSL (默認是啟用(require), libpq包默認不啟用SSL) * fallback_application_name - 失敗時,可以提供一個應用程序名來跟蹤. * connect_timeout - 連接最大等待秒數, 0或者不指定, 表示不確定時間的等待 * sslcert - 證書文件位置, 文件中必須包含PEM編碼的數據 * sslkey - 密鑰文件位置, 文件中必須包含PEM編碼的數據 * sslrootcert - 根證書文件位置, 文件中必須包含PEM編碼的數據

sslmode 支持一下模式

* disable - 禁用SSL * require - 總是使用SSL(跳過驗證) * verify-ca - 總是使用SSL (驗證服務器提供的證書是由可信的CA簽署的) * verify-full - 總是使用SSL(驗證服務器提供的證書是由受信任的CA簽署的,并驗證服務器主機名是否與證書中的主機名匹配)

更多連接字符串參數請參考官方文檔

對包含空格的參數, 需要使用單引號, 如:

"user=pqgotest password='with spaces'"

使用反斜杠進行轉義, 如:

"user=space\ man password='it\'s valid'"

注意: 如果要設置client_encoding連接參數(用于設置連接的編碼), 必須設置為"UTF8", 才能與Postgres匹配,  設置為其他值將會報錯.

除了上面的參數, 在連接字符串中也可以通過后臺設置運行時參數, 詳細運行時參數, 請參考runtime-config

支持libpq的大部分環境變量也支持pq包, 詳細環境變量請參考libpq-envars. 如果沒有設置環境變量且連接字符串也沒有提供該參數,  程序會panic崩潰退出, 字符串參數優先級高于環境變量.

完整"增刪改查"示例代碼

package main  import (   "database/sql"   "encoding/json"   "fmt"   _ "github.com/lib/pq"   "log" )  const (    // Initialize connection constants.   HOST     = "172.16.xx.xx"   PORT     = 31976   DATABASE = "postgres"   USER     = "postgres"   PASSWORD = "xxx" )  func checkError(err error) {   if err != nil {     panic(err)   } }  type Db struct {   db *sql.DB }  // 創建表 func (this *Db) CreateTable() {   // 以水果庫存清單表inventory為例   // Drop previous table of same name if one exists.  如果之前存在清單表, 則刪除該表   _, err := this.db.Exec("DROP TABLE IF EXISTS inventory;")   checkError(err)   fmt.Println("Finished dropping table (if existed)")    // Create table. 創建表, 指定id, name, quantity(數量)字段, 其中id為主鍵   _, err = this.db.Exec("CREATE TABLE inventory (id serial PRIMARY KEY, name VARCHAR(50), quantity INTEGER);")   checkError(err)   fmt.Println("Finished creating table") }  // 刪除表 func (this *Db) DropTable() {   // 以水果庫存清單表inventory為例   // Drop previous table of same name if one exists.  如果之前存在清單表, 則刪除該表   _, err := this.db.Exec("DROP TABLE IF EXISTS inventory;")   checkError(err)   fmt.Println("Finished dropping table (if existed)") }  // 增加數據 func (this *Db) Insert() {   // Insert some data into table. 插入3條水果數據   sql_statement := "INSERT INTO inventory (name, quantity) VALUES ($1, $2);"   _, err := this.db.Exec(sql_statement, "banana", 150)   checkError(err)   _, err = this.db.Exec(sql_statement, "orange", 154)   checkError(err)   _, err = this.db.Exec(sql_statement, "apple", 100)   checkError(err)   fmt.Println("Inserted 3 rows of data") }  // 讀數據/查數據 func (this *Db) Read() {   //讀取數據   // Read rows from table.   var id int   var name string   var quantity int    sql_statement := "SELECT * from inventory;"   rows, err := this.db.Query(sql_statement)   checkError(err)   defer rows.Close()    for rows.Next() {     switch err := rows.Scan(&id, &name, &quantity); err {     case sql.ErrNoRows:       fmt.Println("No rows were returned")     case nil:       fmt.Printf("Data row = (%d, %s, %d)\n", id, name, quantity)     default:       checkError(err)     }   } }   // 更新數據 func (this *Db) Update() {   // Modify some data in table.   sql_statement := "UPDATE inventory SET quantity = $2 WHERE name = $1;"   _, err := this.db.Exec(sql_statement, "banana", 200)   checkError(err)   fmt.Println("Updated 1 row of data") }  // 刪除數據 func (this *Db) Delete() {   // Delete some data from table.   sql_statement := "DELETE FROM inventory WHERE name = $1;"   _, err := this.db.Exec(sql_statement, "orange")   checkError(err)   fmt.Println("Deleted 1 row of data") }  // 數據序列化為Json字符串, 便于人工查看 func Data2Json(anyData interface{}) string {   JsonByte, err := json.Marshal(anyData)   if err != nil {     log.Printf("數據序列化為json出錯:\n%s\n", err.Error())     return ""   }   return string(JsonByte) }   //多行數據解析 func QueryAndParseRows(Db *sql.DB, queryStr string) []map[string]string {   rows, err := Db.Query(queryStr)   defer rows.Close()   if err != nil {     log.Printf("查詢出錯:\nSQL:\n%s, 錯誤詳情\n", queryStr, err.Error())     return nil   }   cols, _ := rows.Columns() //列名   if len(cols) > 0 {     var ret []map[string]string //定義返回的映射切片變量ret     for rows.Next() {       buff := make([]interface{}, len(cols))       data := make([][]byte, len(cols)) //數據庫中的NULL值可以掃描到字節中       for i, _ := range buff {         buff[i] = &data[i]       }       rows.Scan(buff...) //掃描到buff接口中,實際是字符串類型data中        //將每一行數據存放到數組中       dataKv := make(map[string]string, len(cols))       for k, col := range data { //k是index,col是對應的值         //fmt.Printf("%30s:\t%s\n", cols[k], col)         dataKv[cols[k]] = string(col)       }       ret = append(ret, dataKv)     }     log.Printf("返回多元素數組:\n%s", Data2Json(ret))     return ret   } else {     return nil   } }  //單行數據解析 查詢數據庫,解析查詢結果,支持動態行數解析 func QueryAndParse(Db *sql.DB, queryStr string) map[string]string {   rows, err := Db.Query(queryStr)   defer rows.Close()    if err != nil {     log.Printf("查詢出錯:\nSQL:\n%s, 錯誤詳情\n", queryStr, err.Error())     return nil   }   //rows, _ := Db.Query("SHOW VARIABLES LIKE '%data%'")    cols, _ := rows.Columns()   if len(cols) > 0 {     buff := make([]interface{}, len(cols)) // 臨時slice     data := make([][]byte, len(cols))      // 存數據slice     dataKv := make(map[string]string, len(cols))     for i, _ := range buff {       buff[i] = &data[i]     }      for rows.Next() {       rows.Scan(buff...) // ...是必須的     }      for k, col := range data {       dataKv[cols[k]] = string(col)       //fmt.Printf("%30s:\t%s\n", cols[k], col)     }     log.Printf("返回單行數據Map:\n%s", Data2Json(dataKv))     return dataKv   } else {     return nil   } }   func main() {   // Initialize connection string. 初始化連接字符串, 參數包含主機,端口,用戶名,密碼,數據庫名,SSL模式(禁用),超時時間   var connectionString string = fmt.Sprintf("host=%s  port=%d user=%s password=%s dbname=%s sslmode=disable connect_timeout=3", HOST, PORT, USER, PASSWORD, DATABASE)    // Initialize connection object. 初始化連接對象, 驅動名為postgres   db, err := sql.Open("postgres", connectionString)   defer db.Close()   checkError(err)   postgresDb := Db{     db: db,   }   err = postgresDb.db.Ping() //連通性檢查   checkError(err)   fmt.Println("Successfully created connection to database")    postgresDb.CreateTable()         //創建表   postgresDb.Insert()              //插入數據   postgresDb.Read()                //查詢數據   QueryAndParseRows(postgresDb.db, "SELECT * from inventory;") //直接查詢和解析多行數據   QueryAndParse(postgresDb.db, "SHOW DateStyle;") //直接查詢和解析單行數據   postgresDb.Update()              //修改/更新數據   postgresDb.Read()   postgresDb.Delete()              //刪除數據   postgresDb.Read()   postgresDb.DropTable() }

執行 go run main.go運行結果如下:

Successfully created connection to database Finished dropping table (if existed) Finished creating table Inserted 3 rows of data Data row = (1, banana, 150) Data row = (2, orange, 154) Data row = (3, apple, 100) 2020/12/15 22:13:33 返回多元素數組: [{"id":"1","name":"banana","quantity":"150"},{"id":"2","name":"orange","quantity":"154"},{"id":"3","name":"apple","quantity":"100"}] 2020/12/15 22:13:33 返回單行數據Map: {"DateStyle":"ISO, MDY"} Updated 1 row of data Data row = (2, orange, 154) Data row = (3, apple, 100) Data row = (1, banana, 200) Deleted 1 row of data Data row = (3, apple, 100) Data row = (1, banana, 200) Finished dropping table (if existed)

“如何理解Golang牽手PostgreSQL增刪改查+不寫結構快速掃描字段”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

务川| 镇康县| 台北市| 建德市| 利辛县| 太仓市| 霍州市| 嘉峪关市| 萍乡市| 宁安市| 林西县| 惠水县| 菏泽市| 抚宁县| 勐海县| 资溪县| 昭觉县| 苗栗县| 天台县| 娄底市| 甘德县| 兴隆县| 临沂市| 城步| 东丽区| 建昌县| 上犹县| 友谊县| 东阿县| 长宁区| 太仆寺旗| 丽水市| 龙南县| 永吉县| 和林格尔县| 甘肃省| 铁力市| 苗栗县| 余庆县| 福清市| 于田县|