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

Go 在这里使用事先准备好的声明会更好吗?,go,prepared-statement,Go,Prepared Statement,我理解Go/中准备好的声明的好处 假设我有一个结构 type Brand struct { Id int `json:"id,omitempty"` Name string `json:"name,omitempty"` Issued_at *time.Time `json:"issued_at,omitempty"` } 还有一些表品牌,其中id是唯一字段。现在我想使用和id从该表中检索元素 我可以使用QueryRow编写

我理解Go/中准备好的声明的好处

假设我有一个结构

type Brand struct {
    Id        int        `json:"id,omitempty"`
    Name      string     `json:"name,omitempty"`
    Issued_at *time.Time `json:"issued_at,omitempty"`
}
还有一些表
品牌
,其中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请求/内存/任何方面)。或者他们都很烂,我最好做点别的

我读过一本书,我看到:

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


但我认为第二种情况下的prepared语句将在函数末尾被删除。

在这两个示例中,数据库开销大致相同。如果你打算大量使用一条语句,就在更大范围内准备一次,这样它就可以重复使用


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

如果您将数据库与用户输入结合使用,您应该事先准备好语句


否则,您将面临插入数据库的风险(SQL Insertion ex)。

是否有任何东西可以支持此声明。因为现在的情况和我在问题中写的假设是一样的,我希望有可靠的来源来支持这个假设。@Salvadodali根据您链接的文档,Query[Row]只是准备语句,运行语句,然后关闭语句,对吗?在我看来,直觉告诉我,如果你只准备一次语句,然后不断地运行相同的准备语句,你将减少接近3倍的往返次数。您的第一个和第二个示例所做的工作与您在每次函数调用时创建一个新的prepared语句大致相同。这似乎是合理的。谢谢,+1第一个问题没有回答我的问题,第二个参数为$1的queryRow也会为我准备语句,所以你的答案并不正确