#{}的用法:
我們發現,在Mapper.xml映射文件中,經常使用#{屬性名} 來作為SQL語句的占位符,來映射Sql需要的實際參數
如果只有一個參數
<select id="getUserById" parameterType="int" resultType="User">
select * from users where id=#{id}
</select>
也就是說:#{}就是一個預編譯的占位符作用,運行的時候會編譯成 ? ;但這只適用於只有一個參數的情況,而且這種情況#{id}中的id可以寫成任何字符串,比如#{abc}
但是如果我們有多個參數呢?
如果有多個參數
解決方案一:按照順序用 0 1 來標志
<select id="getUserByNameAndAge" resultType="User">
select * from users where username=#{0} and age=#{1}
</select>
解決方案二:按照順序用param1 param2 來標志
<select id="getUserByNameAndAge" resultType="User">
select * from users where username=#{param1} and age=#{param2}
</select>
解決方案三:利用參數
<select id="getUserByNameAndAge" resultType="User">
select * from users where username=#{username123} and age=#{age233}
</select>
public interface UserMapper {
public User getUserByNameAndAge(@Param("username123") String username, @Param("age233") int age);
}
這種方式是推薦方式,不過我們需要注意的是xml和interface中的參數名稱需要對應。
${}的用法:
${}的用法和#{}的用法不同在於: #{}會被編譯成?,而${}則會被原樣輸出(用在參數上,需要用param注解)
<select id="getUserById" parameterType="int" resultType="User">
select * from users where id=${id}
</select>
public interface UserMapper {
public User getUserById(@Param("id") int id);
}

運行的時候 會直接原樣輸出,不能解決sql注入問題,但是這種情況如果參數是字符串或者日期類型的話 需要手動加單引號 不然會報錯;
由於是直接輸出的,所以我們在配置mybatis-config.xml的時候 可以用${}來可以配置一些東西,比如:
<!--加載外部屬性-->
<properties resource="jdbc.properties"/>
<!--運行環境可以配置多個, default指定默認使用哪個-->
<environments default="development">
<!--配置環境, id是這個環境的唯一標識-->
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
總結:
#是占位符, 會對SQL進行預編譯,相當於?; $是做sql拼接, 有SQL注入的隱患 2. #不需要關注數據類型, MyBatis自動實現數據類型轉換; ${} 必須自己判斷數據類型
兩者都支持@param注解, 指定參數名稱, 獲取參數值. 推薦這種方式
一般做參數傳遞,都會使用#{}
如果不是做預編譯,而是做拼接sql, 會使用${}, 例如表名稱的變化,或者用在其他配置文件中
