Mysql golang sql驱动程序';让我们准备一份声明
关于golang的sql驱动程序,下面两个语句之间的区别是什么Mysql golang sql驱动程序';让我们准备一份声明,mysql,go,Mysql,Go,关于golang的sql驱动程序,下面两个语句之间的区别是什么 // store.DB is *sql.DB type rows, err := store.DB.Query(SQL, args ...) // err != nil defer rows.Close() 及 看起来他们是一样的?有什么细微的区别吗 更新: 我们不需要在db.Prepare之后执行许多stmt.Exec或stmt.Query,在每个Prepare之后只执行一个Exec或Query。当我们使用db.Query或db
// store.DB is *sql.DB type
rows, err := store.DB.Query(SQL, args ...)
// err != nil
defer rows.Close()
及
看起来他们是一样的?有什么细微的区别吗
更新:
我们不需要在db.Prepare
之后执行许多stmt.Exec
或stmt.Query
,在每个Prepare
之后只执行一个Exec
或Query
。当我们使用db.Query
或db.Exec
时,我们将参数传递给方法,而不是使用原始SQL字符串(出于安全考虑)
我找到了一个参考链接:这两种方法似乎都在使用预先准备好的语句,有什么区别?这取决于您使用的驱动程序,以及您的DB软件是否支持未准备好的查询 Prepare连接到数据库并创建一个绑定到该数据库连接的prepared语句。执行时,它检查该连接是否仍然可用,如果不可用,则创建一个新连接,重新准备函数,然后运行它 编辑:注意,如果一次只有一个例程连接到数据库,并且使用不同的参数反复运行相同的查询,那么Prepare可以更快,因为它将查询存储在数据库端。然而,其他例程的连接劫持否定了这一点,如果您只使用了一次查询,那么Prepare对您完全没有好处 查询根据驱动程序执行以下两项操作之一。如果驱动程序从
Open()
返回的Conn
类型也有一个Query()
方法,因此支持直接查询,那么sql.Query()
直接调用该方法并返回其结果。如果Conn
没有Query()
方法,sql.Query()
准备一条语句,然后执行它
例如,PostgreSQL的
pq
驱动程序(github.com/lib/pq)有一个Query()
方法。这个方法准备和执行,就像sql
包所做的那样,但也有一个替代方法:如果查询没有参数,它使用simpleQuery
接口执行,包注意到这个接口比准备和执行周期要快得多。差异可能很微妙,有时很重要,有时实际上根本不存在
一般而言,一份准备好的报表1。与服务器一起准备(SQL解析、生成执行计划等),2。使用附加参数执行,然后执行3。关门了。它允许您使用每次传入的不同参数重用相同的SQL,它可以帮助防止SQL注入,可以提供一些性能增强(特定于驱动程序/协议,YMMV)并防止重复步骤,如上面准备步骤中的执行计划生成和SQL解析
对于编写源代码的人来说,准备好的语句可能比连接字符串并将其发送到DB服务器更方便
DB.Query()
方法将SQL作为字符串和零个或多个参数(与Exec()
或QueryRow()
一样)。没有附加参数的SQL字符串将精确查询您编写的内容。但是,如果提供了一个带有占位符和附加参数的SQL字符串,则会在后台为您准备一条语句
DB.Prepare()
就两者之间的差异以及为什么使用其中一种或另一种而言,有一些事情值得思考
您可以使用不带参数的DB.Query()
。这可能非常有效,因为它可以绕过prepare语句必须经过的prepare-->execute-->close序列
您还可以将它与其他参数和查询字符串中的占位符一起使用,它将在前面提到的封面下执行一条准备好的语句。这里潜在的问题是,当您进行大量查询时,每一个查询都会产生一个幕后准备的语句。由于涉及到额外的步骤,这可能会非常低效,因为它会在每次执行该查询时重新准备、执行和关闭
使用显式的prepared语句,您可能会避免这种低效,因为您正试图使用可能不同的参数重用先前准备的SQL
但这并不总是像你预期的那样有效。。。由于底层连接池由db/sql管理,所以您的“数据库连接”相当虚拟。DB.Prepare()。如果你一次又一次地使用同一个事先准备好的语句,那么你可能在不知不觉中也在一次又一次地准备它。很明显,当你面对拥挤的交通时,这一点很容易被发现
很明显,在什么情况下使用哪一个取决于您的具体用例,但我希望上面的细节能够帮助您充分澄清,以便您能够在每种情况下做出最佳决策
更新
鉴于OP中的更新,当查询只需要执行一次时,基本上没有区别,因为带有参数的查询是作为幕后准备的语句来完成的
使用直接方法,例如DB.Query()
及其类似方法,而不是显式使用预先准备好的语句,因为这样会使源代码更加简单
由于在本例中,准备好的语句是出于安全原因而使用的,因此可能值得通过其他方式处理安全问题,并使用明文查询,因为
// store.DB is *sql.DB type
stmt, err := store.DB.Prepare(SQL)
// err != nil
defer stmt.Close()
rows, err := stmt.Query(args ...)
// err != nil
defer rows.Close()