由于ORM
的安全性保障,所有输入的参数在底层都将使用预处理模式执行,防止常见的SQL
注入风险。在某一些场景中,我们期望在生成执行的SQL语句中嵌入自定义的SQL语句,那么我们可以使用ORM
的RawSQL
特性,通过gdb.Raw
类型来实现。我们来看几个示例。
在Insert
中使用RawSQL
gdb.Raw
是字符串类型,该类型的参数将会直接作为SQL
片段嵌入到提交到底层的SQL
语句中,不会被自动转换为字符串参数类型、也不会被当做预处理参数。例如:
// INSERT INTO `user`(`id`,`passport`,`password`,`nickname`,`create_time`) VALUES('id+2','john','123456','now()')
g.Model("user").Data(g.Map{
"id": "id+2",
"passport": "john",
"password": "123456",
"nickname": "JohnGuo",
"create_time": "now()",
}).Insert()
// 执行报错:Error Code: 1136. Column count doesn't match value count at row 1
使用gdb.Raw
改造后:
// INSERT INTO `user`(`id`,`passport`,`password`,`nickname`,`create_time`) VALUES(id+2,'john','123456',now())
g.Model("user").Data(g.Map{
"id": gdb.Raw("id+2"),
"passport": "john",
"password": "123456",
"nickname": "JohnGuo",
"create_time": gdb.Raw("now()"),
}).Insert()
在Update
中使用RawSQL
// UPDATE `user` SET login_count='login_count+1',update_time='now()' WHERE id=1
g.Model("user").Data(g.Map{
"login_count": "login_count+1",
"update_time": "now()",
}).Where("id", 1).Update()
// 执行报错:Error Code: 1136. Column count doesn't match value count at row 1
使用gdb.Raw
改造后:
// UPDATE `user` SET login_count=login_count+1,update_time=now() WHERE id=1
g.Model("user").Data(g.Map{
"login_count": gdb.Raw("login_count+1"),
"update_time": gdb.Raw("now()"),
}).Where("id", 1).Update()
在Select
中使用RawSQL
时间函数now()
将会被转换为字符串作为SQL
参数执行:
// SELECT * FROM `user` WHERE `created_at`<'now()'
g.Model("user").WhereLT("created_at", "now()").All()
使用gdb.Raw
改造后:
// SELECT * FROM `user` WHERE `created_at`<now()
g.Model("user").WhereLT("created_at", gdb.Raw("now()")).All()