#是預處理而$是直接替換
Mybatis在處理#{}時,會將SQL中的#{}替換成占位符?,再使用preparedStatement的set方法來賦值。
而Mybatis在處理 時,是將 {}時,是將 時,是將{}直接替換成變量的值
我們分別使用#{}和${}來查詢userinfo表中名字叫admin的人
@Mapper
public interface UserMapper {Userinfo selectByName(@Param("username") String username);
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.mapper.UserMapper"><select id="selectByName" resultType="com.example.demo.entity.Userinfo">select * from userinfo where username=#{username}</select>
</mapper>
使用單元測試:
@Test
void selectByName() {String name = "admin";Userinfo userinfo = userMapper.selectByName(name);System.out.println("用戶信息:" + userinfo);
}
將#{}變成${}
${}存在sql注入的風險
例如登入場景,需要輸入用戶名和密碼,如果使用${}就存在sql注入的風險。
什么是sql注入
SQL注入應用程序對用戶輸入數據的合法性沒有判斷或者過濾不嚴,攻擊者利用SQL語法,拼接上一些特殊的sql語句,欺騙MySQL執行一些非授權的任意查詢。最經典的sql注入就是' or 1='1"
<select id="login" resultType="com.example.demo.entity.Userinfo">select * from userinfo whereusername='${username}' and password = '${password}'
</select>
得到的結果如下:
也就是使用${}通過直接替換到sql語句中,是直接當作SQL語句的一部分,替換進去的是依據SQL語法可以實現拆分使用,而使用#{}通過占位符,把傳進去的參數當作一個整體使用。
${}的使用場景
在開發中大部分是使用#{},但存在即合理。當我們傳遞的參數是SQL關鍵字時,使用${}。
例如,淘寶中價格從高到低需要傳遞參數desc,此時不能使用#{},不然會將desc認為是string類型。
注意:在使用${}時,傳過來的參數一定是可枚舉的,要經過檢查才能使用