由于 ORM 的安全性保障,所有输入的参数在底层都将使用预处理模式执行,防止常见的 SQL 注入风险。在某一些场景中,我们期望在生成执行的SQL语句中嵌入自定义的SQL语句,那么我们可以使用 ORMRawSQL 特性,通过 gdb.Raw 类型来实现。我们来看几个示例。

Insert 中使用 RawSQL

gdb.Raw 是字符串类型,该类型的参数将会直接作为 SQL 片段嵌入到提交到底层的 SQL 语句中,不会被自动转换为字符串参数类型、也不会被当做预处理参数。例如:

  1. // INSERT INTO `user`(`id`,`passport`,`password`,`nickname`,`create_time`) VALUES('id+2','john','123456','now()')
  2. g.Model("user").Data(g.Map{
  3. "id": "id+2",
  4. "passport": "john",
  5. "password": "123456",
  6. "nickname": "JohnGuo",
  7. "create_time": "now()",
  8. }).Insert()
  9. // 执行报错:Error Code: 1136. Column count doesn't match value count at row 1

使用 gdb.Raw 改造后:

  1. // INSERT INTO `user`(`id`,`passport`,`password`,`nickname`,`create_time`) VALUES(id+2,'john','123456',now())
  2. g.Model("user").Data(g.Map{
  3. "id": gdb.Raw("id+2"),
  4. "passport": "john",
  5. "password": "123456",
  6. "nickname": "JohnGuo",
  7. "create_time": gdb.Raw("now()"),
  8. }).Insert()

Update 中使用 RawSQL

  1. // UPDATE `user` SET login_count='login_count+1',update_time='now()' WHERE id=1
  2. g.Model("user").Data(g.Map{
  3. "login_count": "login_count+1",
  4. "update_time": "now()",
  5. }).Where("id", 1).Update()
  6. // 执行报错:Error Code: 1136. Column count doesn't match value count at row 1

使用 gdb.Raw 改造后:

  1. // UPDATE `user` SET login_count=login_count+1,update_time=now() WHERE id=1
  2. g.Model("user").Data(g.Map{
  3. "login_count": gdb.Raw("login_count+1"),
  4. "update_time": gdb.Raw("now()"),
  5. }).Where("id", 1).Update()

Select 中使用 RawSQL

时间函数 now() 将会被转换为字符串作为 SQL 参数执行:

  1. // SELECT * FROM `user` WHERE `created_at`<'now()'
  2. g.Model("user").WhereLT("created_at", "now()").All()

使用 gdb.Raw 改造后:

  1. // SELECT * FROM `user` WHERE `created_at`<now()
  2. g.Model("user").WhereLT("created_at", gdb.Raw("now()")).All()