# 和 $ 的区别②

上节博客说了使用 # 的时候,如果参数为 String ,会自动加上单引号

但是当参数为String 类型的时候,也有不需要加单引号的情况,这时候用 # 那就会出问题

比如根据 升序(asc) 或者 降序(desc) 查找的时候,加了单引号那就会报错

这个时候我们就只能使用 $ 

如果看不懂代码,就去看<<Mybatis 的操作(结合上文)续集>>,我这里为了简练一点就不多解释了

@Select("select * from userinfo order by id ${sort}")
    List<UserInfo> selectUserBySort(String sort);
 @Test
    void selectUserBySort() {
        log.info(userInfoMapper.selectUserBySort("asc").toString());
    }

使用 $ 才能正常运行 

还有一种情况不能使用 # ,那就是模糊查询 

进行模糊查询的时候也只能用 $

@Select("select * from userinfo where username like'%${username}%'")
    List<UserInfo> selectUserByLike(String username);
@Test
    void selectUserByLike() {
        log.info(userInfoMapper.selectUserByLike("java").toString());
    }

 有的人可能会觉得那我们在排序和模糊查询的时候使用 $ ,其他有需要引号的情况只要拼接上引号也可以使用 $ ,那我们就不用 # 了吗?

这是不可以滴,因为 $ 存在 SQL 注入的问题

打个比方 : 

select * from userinfo where username = 'admin';

若是此时把admin换成 'or 1='1  ,那就变成了

select * from userinfo where username = ''or 1='1';

(这样前面两个引号就会形成一对,后面两个引号形成一对,这就导致where后面的搜索条件变成username=0或者1=1,因为1=1肯定恒成立,这样运行出来的结果就是搜索到全部数据,这与我们的想法背道而驰)

那这肯定就不对了呀,这就是 SQL 注入

# 就不会存在 SQL 注入的问题

我们用代码进行验证看看,先验证 $

    @Select("select * from userInfo where username = '${username}'")
    List<UserInfo> selectByName(String username);
  @Test
    void selectByName() {
        log.info(userInfoMapper.selectByName("'or 1='1").toString());
    }

 很明显把所有数据都给查出来了,这是错误的

接下来我们试试 #

@Select("select * from userInfo where username = #{username}")
    List<UserInfo> selectByName(String username);
 @Test
    void selectByName() {
        log.info(userInfoMapper.selectByName("'or 1='1").toString());
    }

因为没有名为 'or 1='1 的数据,所以啥也没查出来,没问题

同样是加引号,为什么# 不会发生SQL注入的问题?

SQL 执行的过程为 : 1.语法解析 2.SQL优化 3.SQL编译

然后呢, # 是预编译SQL,将编译一次之后的SQL语句缓存起来了,后面再次执行的时候,省去了解析优化等过程,提高了效率,预编译SQL也可以说是一个模版,往里套数据就行.

比如 select * from userinfo where username = '_____';

预编译SQL就只给你留下了这个位置,你填进去之后就只能是 username 的参数

而即时SQL就是你传的参数是什么就现场进行拼接,拼出来之后再对这条语句进行上面三个过程

所以这就是为什么 # 不会发生 SQL 注入的原因

但是在进行排序的时候,只能使用 $ 的时候,发生SQL注入怎么办呢?

可以进行参数校验,只要不是 asc 和 desc 就不接收这个请求

模糊查询的时候使用Mysql的内置函数

 

@Select("select * from userinfo where username like CONCAT('%',#{username},'%')")
    List<UserInfo> selectUserByLike(String username);
 @Test
    void selectUserByLike() {
        log.info(userInfoMapper.selectUserByLike("java").toString());
    }

 

相关推荐

  1. “==”“equals”区别

    2023-12-15 08:28:05       41 阅读
  2. == equals 区别

    2023-12-15 08:28:05       35 阅读
  3. #{}${}区别

    2023-12-15 08:28:05       22 阅读
  4. &&&区别

    2023-12-15 08:28:05       14 阅读
  5. 振动震动区别

    2023-12-15 08:28:05       106 阅读
  6. axiosajax区别

    2023-12-15 08:28:05       39 阅读

最近更新

  1. TCP协议是安全的吗?

    2023-12-15 08:28:05       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2023-12-15 08:28:05       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2023-12-15 08:28:05       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2023-12-15 08:28:05       18 阅读

热门阅读

  1. 二叉树中的中序遍历、反向遍历和逆序

    2023-12-15 08:28:05       36 阅读
  2. Leetcode -2

    2023-12-15 08:28:05       33 阅读
  3. 项目中使用临时文件夹或获取文件资源路径

    2023-12-15 08:28:05       40 阅读
  4. Numpy库

    2023-12-15 08:28:05       37 阅读
  5. uniapp微信小程序下载保存图片流到本地,base64

    2023-12-15 08:28:05       47 阅读
  6. MSSQL存储过程的功能和用法

    2023-12-15 08:28:05       37 阅读
  7. 华为大数据开发者教程知识点提纲

    2023-12-15 08:28:05       29 阅读
  8. Servlet

    Servlet

    2023-12-15 08:28:05      28 阅读
  9. WPF中DataGrid设置默认选中行

    2023-12-15 08:28:05       40 阅读
  10. OpenCV开发:编译安装opencv

    2023-12-15 08:28:05       40 阅读