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()
结论
插值模式纯文本模式插值模式