<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
本篇文章對如何使用golang連線並操作postgre資料庫進行了簡要說明。文中使用到的主要工具:DBeaver21、VSCode,Golang1.17。
以使用者,文章,評論三個表作為例子,下面是資料庫建表sql:
CREATE TABLE public.user_info ( u_id serial4 NOT NULL, user_name varchar NULL, create_time date NULL, CONSTRAINT user_info_pk PRIMARY KEY (u_id) ); CREATE TABLE public.user_info ( u_id serial4 NOT NULL, user_name varchar NULL, create_time date NULL, CONSTRAINT user_info_pk PRIMARY KEY (u_id) ); CREATE TABLE public."comment" ( c_id serial4 NOT NULL, "content" varchar NULL, CONSTRAINT comment_pk PRIMARY KEY (c_id) );
連線postgre資料庫的驅動有很多,我們選用了github.com/lib/pq
。下面看連線的方法。我們引入pq
包時使用了_
進行匿名載入,而不是直接使用驅動包。在對資料庫的操作仍然是使用自帶的sql
包。另外,postgre預設使用的是public
模式(schema),我們建立的表也是在這個模式下的。可以直接在資料庫中修改預設模式或者在連線url中新增currentSchema=myschema
來指定預設的模式,當然也可以在sql中使用myschema.TABLE
來指定要存取的模式。
package main import ( "database/sql" "fmt" _ "github.com/lib/pq" ) var db *sql.DB func DbOpen() { var err error //引數根據自己的資料庫進行修改 db, err = sql.Open("postgres", "host=localhost port=5432 user=angelhand password=2222 dbname=ahdb sslmode=disable") checkError(err) err = db.Ping() checkError(err) }
需要注意的是,sql.DB
並不是資料庫連線,而是一個go中的一個資料結構:
type DB struct { // Atomic access only. At top of struct to prevent mis-alignment // on 32-bit platforms. Of type time.Duration. waitDuration int64 // Total time waited for new connections. connector driver.Connector // numClosed is an atomic counter which represents a total number of // closed connections. Stmt.openStmt checks it before cleaning closed // connections in Stmt.css. numClosed uint64 mu sync.Mutex // protects following fields freeConn []*driverConn connRequests map[uint64]chan connRequest nextRequest uint64 // Next key to use in connRequests. numOpen int // number of opened and pending open connections // Used to signal the need for new connections // a goroutine running connectionOpener() reads on this chan and // maybeOpenNewConnections sends on the chan (one send per needed connection) // It is closed during db.Close(). The close tells the connectionOpener // goroutine to exit. openerCh chan struct{} closed bool dep map[finalCloser]depSet lastPut map[*driverConn]string // stacktrace of last conn's put; debug only maxIdleCount int // zero means defaultMaxIdleConns; negative means 0 maxOpen int // <= 0 means unlimited maxLifetime time.Duration // maximum amount of time a connection may be reused maxIdleTime time.Duration // maximum amount of time a connection may be idle before being closed cleanerCh chan struct{} waitCount int64 // Total number of connections waited for. maxIdleClosed int64 // Total number of connections closed due to idle count. maxIdleTimeClosed int64 // Total number of connections closed due to idle time. maxLifetimeClosed int64 // Total number of connections closed due to max connection lifetime limit. stop func() // stop cancels the connection opener. }
在拿到sql.DB
時並不會建立新的連線,而可以認為是拿到了一個資料庫連線池,只有在執行資料庫操作(如Ping()操作)時才會自動生成一個連線並連線資料庫。在連線操作執行完畢後應該及時地釋放。此處說的釋放是指釋放連線而不是sql.DB
連線,通常來說一個sql.DB
應該像全域性變數一樣長期儲存,而不要在某一個小函數中都進行Open()
和Close()
操作,否則會引起資源耗盡的問題。
下面程式碼實現對資料簡單的增刪改查操作。
func insert() { stmt, err := db.Prepare("INSERT INTO user_info(user_name,create_time) VALUES($1,$2)") if err != nil { panic(err) } res, err := stmt.Exec("ah", time.Now()) if err != nil { panic(err) } fmt.Printf("res = %d", res) }
使用Exec()
函數後會返回一個sql.Result
即上面的res
變數接收到的返回值,它提供了LastInserId() (int64, error)
和RowsAffected() (int64, error)
分別獲取執行語句返回的對應的id和語句執行所影響的行數。
func update() { stmt, err := db.Prepare("update user_info set user_name=$1 WHERE u_id=$2") if err != nil { panic(err) } res, err := stmt.Exec("angelhand", 1) if err != nil { panic(err) } fmt.Printf("res = %d", res) }
結構體如下:
type u struct { id int user_name string create_time time.Time }
接下來是查詢的程式碼
func query() { rows, err := db.Query("select u_id, user_name, create_time from user_info where user_name=$1", "ah") if err != nil { panic(err) } //延遲關閉rows defer rows.Close() for rows.Next() { user := u{} err := rows.Scan(&user.id, &user.user_name, &user.create_time) if err != nil { panic(err) } fmt.Printf("id = %v, name = %v, time = %vn", user.id, user.user_name, user.create_time) } }
可以看到使用到的幾個關鍵函數rows.Close()
,rows.Next()
,rows.Scan()
。其中rows.Next()
用來遍歷從資料庫中獲取到的結果集,隨用用rows.Scan()
來將每一列結果賦給我們的結構體。
需要強調的是rows.Close()
。每一個開啟的rows
都會佔用系統資源,如果不能及時的釋放那麼會耗盡系統資源。defer
語句類似於java中的finally
,功能就是在函數結束前執行後邊的語句。換句話說,在函數結束前不會執行後邊的語句,因此在耗時長的函數中不建議使用這種方式釋放rows
連線。如果要在迴圈中重發查詢和使用結果集,那麼應該在處理完結果後顯式呼叫rows.Close()
。
db.Query()
實際上等於建立db.Prepare()
,執行並關閉之三步操作。
還可以這樣來查詢單條記錄:
err := db.Query("select u_id, user_name, create_time from user_info where user_name=$1", "ah").Scan(&user.user_name)
func delete() { stmt, err := db.Prepare("delete from user_info where user_name=$1") if err != nil { panic(err) } res, err := stmt.Exec("angelhand") if err != nil { panic(err) } fmt.Printf("res = %d", res) }
到此這篇關於Golang連線並操作PostgreSQL資料庫基本操作的文章就介紹到這了,更多相關Golang連線操作PostgreSQL內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45