在这里使用准备好的声明会更好吗?

时间:2016-06-14 03:32:04

标签: go prepared-statement

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而言)。或者可能他们都很糟糕,我会更好地做其他事情。

我已阅读thisfollowed up link,我看到了:

  

db.Query()实际上准备,执行和关闭准备好的   声明。这是数据库的三次往返。如果你不是   小心,您可以将数据库交互次数增加三倍   应用程序

但我认为第二种情况下的准备声明将在函数结束时删除。

2 个答案:

答案 0 :(得分:3)

在这两个示例中,数据库开销大致相同。如果您要使用很多声明,请在更广泛的范围内准备一次,以便它可以重复使用。

您只能使用该模式进行一次往返数据库。

答案 1 :(得分:0)

如果您曾经将数据库与用户输入结合使用,则应始终事先准备好语句。

如果没有,则存在DB插入风险(SQL Insertion ex)。