2016-06-14 82 views
3

I stillstruggle瞭解準備好聲明在Go/psql的好處。在這裏使用準備好的語句會更好嗎?

假設我有一個結構

type Brand struct { 
    Id  int  `json:"id,omitempty"` 
    Name  string  `json:"name,omitempty"` 
    Issued_at *time.Time `json:"issued_at,omitempty"` 
} 

還有一些表brands,其中id是一個獨特的領域。現在我想使用和id從表中檢索元素。

我可以使用QueryRow編寫以下函數。

func GetBrand1(id int) (Brand, error) { 
    brand := Brand{} 
    if err := Db.QueryRow("SELECT name, issued_at FROM brands WHERE id = $1", id).Scan(&brand.Name, &brand.Issued_at); err != nil { 
     if err == sql.ErrNoRows { 
      return brand, nil 
     } 

     return brand, err 
    } 

    brand.Id = id 
    return brand, nil 
} 

,我可以用準備好的聲明中做同樣的(我希望它是一樣的):

func GetBrand2(id int) (Brand, error) { 
    brand := Brand{} 

    stmt, err := Db.Prepare("SELECT name, issued_at FROM brands WHERE id = $1") 
    if err != nil { 
     return brand, err 
    } 
    defer stmt.Close() 

    rows, err := stmt.Query(id) 
    if err != nil { 
     return brand, err 
    } 
    defer rows.Close() 

    for rows.Next() { 
     rows.Scan(&brand.Name, &brand.Issued_at) 
     brand.Id = id 
     return brand, err 
    } 
    if err = rows.Err(); err != nil { 
     return brand, err 
    } 

    return brand, err 
} 

現在在我的應用我計劃執行GetBrand*功能很多次(與不同的參數)。 Will是其中一個實現比另一個更好(根據sql-requests/memory/anything)。或者可能是他們都吮吸,我會更好地做其他事情。

我已閱讀thisfollowed up link,我看到的是:

db.Query()實際上準備,執行和關閉一個準備 聲明。這是對數據庫的三次往返。如果你不小心 ,你可以翻三倍數據庫的交互次數的 應用使得

,但我認爲,在第二種情況下事先準備好的聲明將在函數結束時被刪除。

+0

[This might help](https://stackoverflow.com/questions/37683218/golang-sql-drivers-prepare-statement/37686891#37686891) – Snowman

回答

3

在這兩個示例中,數據庫開銷大致相同。如果你打算使用一個陳述,在一個更寬的範圍內準備一次,這樣它就可以重用。

您將只使用該模式進行一次往返數據庫。

+0

有什麼要備份這一說法。因爲它現在的樣子,這與我在我的問題中寫下的假設是一樣的,我想有一些可信的來源來支持這個假設。 –

+1

@SalvadorDali根據你鏈接的文檔Query [Row]只是準備語句,運行它並關閉它,對吧? 對我來說,如果你準備好這個陳述一次,然後不斷運行相同的準備陳述,你會減少往返的因數接近3. 你的第一個和第二個例子都做了大致相同的事情因爲您在每次函數調用時都會創建一個新的準備好的語句。 –

+0

似乎合理。謝謝+1 –

0

如果您曾經將數據庫與用戶輸入結合使用,則應該始終事先準備好聲明。

如果不是,則存在數據庫插入(SQL插入前)的風險。

+0

首先,這並不回答我的問題,第二個queryRow帶參數$ 1也會爲我準備好聲明,所以你的回答並不是真的正確 –