我still struggle了解准备好的陈述在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而言)。或者可能他们都很糟糕,我会更好地做其他事情。
我已阅读this和followed up link,我看到了:
db.Query()实际上准备,执行和关闭准备好的 声明。这是数据库的三次往返。如果你不是 小心,您可以将数据库交互次数增加三倍 应用程序
但我认为第二种情况下的准备声明将在函数结束时删除。
答案 0 :(得分:3)
在这两个示例中,数据库开销大致相同。如果您要使用很多声明,请在更广泛的范围内准备一次,以便它可以重复使用。
您只能使用该模式进行一次往返数据库。
答案 1 :(得分:0)
如果您曾经将数据库与用户输入结合使用,则应始终事先准备好语句。
如果没有,则存在DB插入风险(SQL Insertion ex)。