MyBatis中#和$符的区别,sql注入问题,动态sql语句

MyBatis中#{}和${}的区别

  1. #{}和${}都是MyBatis提供的sql参数替换。区别是:
  2. #{}是预编译处理,${}是字符串直接替换。
  3. #{}可以防止SQL注入,${}存在SQL注入的风险,例如  “' or 1='1”
  4. 虽然存在SQL注入风险,但也有自己的适用场景,比如排序功能,表名,字段名等作为参数传入时。
  5. #{}模糊查询要搭配使用mysql内置的拼接函数concat,安全性高。模糊查询虽然${}可以完成,但是存在SQL注入,不安全。

直接替换是指:是MyBatis 在处理 ${} 时,就是把 ${} 替换成变量的值。

预编译处理是指:MyBatis 在处理#{}时,会将 SQL 中的 #{} 替换为?号,使⽤ PreparedStatement 的 set ⽅法来赋值。

$是直接替换,传入的SQL参数若遇到String类型时,不会自动加单/双引号,就会报错,必须加单/双引号才不出错。并且还有sql注入问题。不过$也有自己的使用场景,比如排序,传入desc,asc字符串时,是不需要加单/双引号的。此时就可以用$,并且这两个字符串不让用户自己传,直接给升序,降序按钮,也就避免了sql注入风险。能发生SQL注入主要还是为用户提供了输入框,用户能传参。

而#无论是Integer类型,还是String类型,都会提前预编译,预编译SQL,而且预编译SQL的性能更高。遇到String类型会自动加单/双引号。

以模糊查询为例,${}和#{}的使用区别

  • 使用${},但存在SQL注入风险。
  • 使用#{},更安全,更高效。

SQL注入问题${}

代码演示,所传参数后跟  ' or '1=1 。就会查出全结果集。

bookMapper.getBookByN("平凡的世界' or '1=1");  //传入参数
select * from book_info where book_name = '${bookName}'; //SQL语句

SQL日志打印:


动态 SQL 语法

1.标签
  • 使用场景:当我们在输入个人信息的时候,不一定都得填写(必填项+非必填项),这时候有的参数就为空。所以在插入时就得判空。
    
            insert into userinfo {
                username,
                password,
                nickname,
                 //test中的sex是属性,不是字段
                    sex,
                
                }
                birthday
            )values (
                #{username},
                #{password},
                #{nickname},
                 //test中的这里的sex是属性
                   #{sex},
                
                #{birthday}
            )
    

注意 test 中的 sex,是传⼊对象中的属性,不是数据库字段。


2.标签

prefix:表示整个语句块,以prefix的值作为前缀

suffix:表示整个语句块,以suffix的值作为后缀

prefixOverrides:表示整个语句块要去除掉的前缀

suffixOverrides:表示整个语句块要去除掉的后缀

  • 如果输入参数全是非必填项。就需要if标签和trim标签相结合。
     
            insert into userinfo
            
                username, //别忘记逗号
                password, //test中的是属性,不是字段
                nickname,
                sex,
                birthday,
            
            
                #{username},
                #{nickname},
                #{sex},
                #{birthday},
            
      

3.标签
  • 对于where后跟的参数是否为空,不清楚时。
    

以上标签也可以使⽤ 替换。


4.标签
  • 动态update操作
    //parameterType 为传入参数的类型
    
        update userinfo
        
            username = #{username},
            password = #{password},
            nickname = #{nickname},
            sex = #{sex},
            birthday = #{birthday},
        
        where = #{id}
    

以上标签也可以使⽤ 替换。


5.标签
  • 遍历集合(如List)时,可以使用,例如批量删除等操作。
    // collection 集合类型  item集合名
    
        delete from userinfo where id in
        
            #{list}
        
    

你可能感兴趣的:(mybatis,数据库,SQL注入)