欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Golang連接并操作PostgreSQL數(shù)據(jù)庫基本操作

 更新時(shí)間:2022年09月16日 11:45:58   作者:天使手兒  
PostgreSQL是常見的免費(fèi)的大型關(guān)系型數(shù)據(jù)庫,具有豐富的數(shù)據(jù)類型,也是軟件項(xiàng)目常用的數(shù)據(jù)庫之一,下面這篇文章主要給大家介紹了關(guān)于Golang連接并操作PostgreSQL數(shù)據(jù)庫基本操作的相關(guān)資料,需要的朋友可以參考下

前言:

本篇文章對(duì)如何使用golang連接并操作postgre數(shù)據(jù)庫進(jìn)行了簡要說明。文中使用到的主要工具:DBeaver21、VSCode,Golang1.17。

以用戶,文章,評(píng)論三個(gè)表作為例子,下面是數(shù)據(jù)庫建表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)
);

連接數(shù)據(jù)庫

連接postgre數(shù)據(jù)庫的驅(qū)動(dòng)有很多,我們選用了github.com/lib/pq。下面看連接的方法。我們引入pq包時(shí)使用了_進(jìn)行匿名加載,而不是直接使用驅(qū)動(dòng)包。在對(duì)數(shù)據(jù)庫的操作仍然是使用自帶的sql包。另外,postgre默認(rèn)使用的是public模式(schema),我們創(chuàng)建的表也是在這個(gè)模式下的。可以直接在數(shù)據(jù)庫中修改默認(rèn)模式或者在連接url中添加currentSchema=myschema來指定默認(rèn)的模式,當(dāng)然也可以在sql中使用myschema.TABLE來指定要訪問的模式。

package main

import (
    "database/sql"
    "fmt"

    _ "github.com/lib/pq"
)

var db *sql.DB

func DbOpen() {
    var err error
    //參數(shù)根據(jù)自己的數(shù)據(jù)庫進(jìn)行修改
    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

需要注意的是,sql.DB并不是數(shù)據(jù)庫連接,而是一個(gè)go中的一個(gè)數(shù)據(jù)結(jié)構(gòu):

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時(shí)并不會(huì)創(chuàng)建新的連接,而可以認(rèn)為是拿到了一個(gè)數(shù)據(jù)庫連接池,只有在執(zhí)行數(shù)據(jù)庫操作(如Ping()操作)時(shí)才會(huì)自動(dòng)生成一個(gè)連接并連接數(shù)據(jù)庫。在連接操作執(zhí)行完畢后應(yīng)該及時(shí)地釋放。此處說的釋放是指釋放連接而不是sql.DB連接,通常來說一個(gè)sql.DB應(yīng)該像全局變量一樣長期保存,而不要在某一個(gè)小函數(shù)中都進(jìn)行Open()Close()操作,否則會(huì)引起資源耗盡的問題。

增刪改查

下面代碼實(shí)現(xiàn)對(duì)數(shù)據(jù)簡單的增刪改查操作。

插入數(shù)據(jù)

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()函數(shù)后會(huì)返回一個(gè)sql.Result即上面的res變量接收到的返回值,它提供了LastInserId() (int64, error)RowsAffected() (int64, error)分別獲取執(zhí)行語句返回的對(duì)應(yīng)的id和語句執(zhí)行所影響的行數(shù)。

更新數(shù)據(jù)

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)
}

查詢數(shù)據(jù)

結(jié)構(gòu)體如下:

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)

    }
    //延遲關(guān)閉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 = %v\n", user.id, user.user_name, user.create_time)
    }
}

可以看到使用到的幾個(gè)關(guān)鍵函數(shù)rows.Close(),rows.Next(),rows.Scan()。其中rows.Next()用來遍歷從數(shù)據(jù)庫中獲取到的結(jié)果集,隨用用rows.Scan()來將每一列結(jié)果賦給我們的結(jié)構(gòu)體。

需要強(qiáng)調(diào)的是rows.Close()。每一個(gè)打開的rows都會(huì)占用系統(tǒng)資源,如果不能及時(shí)的釋放那么會(huì)耗盡系統(tǒng)資源。defer語句類似于java中的finally,功能就是在函數(shù)結(jié)束前執(zhí)行后邊的語句。換句話說,在函數(shù)結(jié)束前不會(huì)執(zhí)行后邊的語句,因此在耗時(shí)長的函數(shù)中不建議使用這種方式釋放rows連接。如果要在循環(huán)中重發(fā)查詢和使用結(jié)果集,那么應(yīng)該在處理完結(jié)果后顯式調(diào)用rows.Close()。

db.Query()實(shí)際上等于創(chuàng)建db.Prepare(),執(zhí)行并關(guān)閉之三步操作。

還可以這樣來查詢單條記錄:

err := db.Query("select u_id, user_name, create_time from user_info where user_name=$1", "ah").Scan(&user.user_name)

刪除數(shù)據(jù)

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)
}

總結(jié)

到此這篇關(guān)于Golang連接并操作PostgreSQL數(shù)據(jù)庫基本操作的文章就介紹到這了,更多相關(guān)Golang連接操作PostgreSQL內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • go語言的sql包原理與用法分析

    go語言的sql包原理與用法分析

    這篇文章主要介紹了go語言的sql包原理與用法,較為詳細(xì)的分析了Go語言里sql包的結(jié)構(gòu)、相關(guān)函數(shù)與使用方法,需要的朋友可以參考下
    2016-07-07
  • golang配置管理神器Viper使用教程

    golang配置管理神器Viper使用教程

    這篇文章主要為大家介紹了golang配置管理神器Viper使用教程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪
    2022-04-04
  • Golang處理gRPC請(qǐng)求/響應(yīng)元數(shù)據(jù)的示例代碼

    Golang處理gRPC請(qǐng)求/響應(yīng)元數(shù)據(jù)的示例代碼

    前段時(shí)間實(shí)現(xiàn)內(nèi)部gRPC框架時(shí),為了實(shí)現(xiàn)在服務(wù)端攔截器中打印請(qǐng)求及響應(yīng)的頭部信息,便查閱了部分關(guān)于元數(shù)據(jù)的資料,因?yàn)橹形木W(wǎng)絡(luò)上對(duì)于該領(lǐng)域的信息較少,于是在這做了一些簡單的總結(jié),需要的朋友可以參考下
    2024-03-03
  • go語言中slice,map,channl底層原理

    go語言中slice,map,channl底層原理

    這篇文章主要介紹了go語言中slice,map,channl底層原理,slice,map,channl是我們Go語言中最最常用的幾個(gè)數(shù)據(jù)結(jié)構(gòu),對(duì)于其更多相關(guān)內(nèi)容需要的小伙伴可以參考下面文章詳細(xì)內(nèi)容
    2022-06-06
  • go語言?nil使用避坑指南

    go語言?nil使用避坑指南

    這篇文章主要為大家介紹了go語言?nil使用避坑指南詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-09-09
  • 詳解Go 語言中的比較操作符

    詳解Go 語言中的比較操作符

    這篇文章專注于 6 個(gè)操作符,==,!=,<,<=,> 和 >=。我們將深入探討它們的語法和用法的細(xì)微差別,感興趣的朋友跟隨腳本之家小編一起看看吧
    2018-08-08
  • 使用dep 配置golang 開發(fā)環(huán)境的操作方法

    使用dep 配置golang 開發(fā)環(huán)境的操作方法

    下面小編就為大家?guī)硪黄褂胐ep 配置golang 開發(fā)環(huán)境的操作方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-09-09
  • go語言版的ip2long函數(shù)實(shí)例

    go語言版的ip2long函數(shù)實(shí)例

    這篇文章主要介紹了go語言版的ip2long函數(shù),實(shí)例分析了Go語言實(shí)現(xiàn)的ip2long函數(shù)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-02-02
  • golang中defer的基本使用教程

    golang中defer的基本使用教程

    go語言中defer可以完成延遲功能,當(dāng)前函數(shù)執(zhí)行完成后再執(zhí)行defer的代碼塊,下面這篇文章主要給大家介紹了關(guān)于golang中defer基本使用的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-06-06
  • Mac下Vs code配置Go語言環(huán)境的詳細(xì)過程

    Mac下Vs code配置Go語言環(huán)境的詳細(xì)過程

    這篇文章給大家介紹Mac下Vs code配置Go語言環(huán)境的詳細(xì)過程,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2021-07-07

最新評(píng)論