Go

go-sql-driver/mysqlQuery()Exec()Query()

两种模式

Query(query string, args ...interface{})args

纯文本模式

argsQuery(query)纯文本模式

在此模式中, 驱动程序不对查询字符串进行任何操作, 而是直接将其发送到 MySQL 服务器.

插值模式

?args

在此模式中, 驱动程序实际执行 3 个动作

args
Prepare Once, Execute Many

区别

SQL 注入

prepare
id name
1 name1
2 name2
3 name3
select id, name from prepare where id = 1;

其返回

id name
1 name1

还不错. 好的, 接下来我们看看如何在前面说的两种模式下实现它.

  • 纯文本模式
func plaintextQuery(db *sql.DB, id string) *sql.Row {
    return db.Query("select id, name from prepare where id = " + id + ";")
}
  • 插值模式
func interpolationQuery(db *sql.DB, id string) *sql.Row {
    return db.Query("select id, name from prepare where id = ?;", id)
}

当你将 "1" 作为 id 传递时, 一切都会正常. 但是, 真的没问题嘛? 我们来尝试一个 SQL 注入案例, 将 "1 or 1 = 1" 作为 id 传递.

interpolationQuery()plaintextQuery()

性能

我分别用两种模式做了一个简单的插入 SQL.

Inserts Number:  100000
Plaintext Mode
Duration 16.058662357s
Interpolation Mode
Duration 24.076297264s
纯文本模式插值模式插值模式Query()Exec()

结论

插值模式纯文本模式插值模式