#{} 导致 sql 语法分析错误

1. #{} 与 ${} 的区别

  • 要了解这个坑就要先了解 #{}${} 的区别[1.2]

    #{}${}
    变量替换变量替换后会自动加上单引号变量替换后不会加上单引号
    sql 注入能防止 sql 注入不能防止 sql 注入
    拼接 sql 方式以预编译的形式,将参数设置到 sql 语句中,使用的是 PreparedStatement直接拼装在 sql 语句中
    效率较低较高

2. 我的问题

  • 我的问题是变量替换时添加单引号所导致的

    • mybatis 查询语句

      <!-- table_name = "time_list"-->
      SELECT COU_TIME FROM #{table_name} WHERE SD > 0 ORDER BY COU_TIME
      
    • 报错

      ### SQL: SELECT COU_TIME FROM ? WHERE SD > 0 ORDER BY COU_TIME
      ### Cause: java.sql.SQLException: 语法分析出错
      
    • 分析后的 sql 语句

      SELECT COU_TIME FROM 'time_list' WHERE SD > 0 ORDER BY COU_TIME
      
    • 正确的 sql 语句

      SELECT COU_TIME FROM time_list WHERE SD > 0 ORDER BY COU_TIME
      

3. 使用建议

  • #{}${} 在使用中的技巧和建议[1]

    • 不论是单个参数,还是多个参数,一律都建议使用注解 @Param("")

    • 能用 #{} 的地方就用 #{},不用或少用 ${},防止 sql 注入。如传递 sql 字段值:

      --column_name = "why"
      select * from user where name = #{column_name} --mybatis
      select * from user order by name = 'why'	   --sql
      
    • 表名作参数时,必须用 ${}。如:

      --table_name = "user"
      select * from ${table_name} --mybatis
      select * from user          --sql
      
    • order by 时,必须用 ${}。如:

      --column_name = "id"
      select * from user order by ${column_name}。
      select * from user order by id
      
    • 使用 ${}#{} 时,要注意 mybatis 传递的参数在 sql 语句中是否可加单引号。

4. 参考资料

[1] 落落的大方. MyBatis中#{}和${}[EO/BL]. https://blog.csdn.net/weixin_46155048/article/details/109348345, 2020-10-28/2021-04-27.

[2] 大脸猫aaaaa. mybatis 中的#{} 和 ${}[EO/BL]. https://blog.csdn.net/weixin_43832730/article/details/112094261, 2020-01-02/2021-04-27.

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值