2016-06-14 133 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也会为我准备好声明,所以你的回答并不是真的正确 –