Mybatis #和$獲取參數值的區別以及@param的使用場景

Mybatis 中$與#的區別

1 #是將傳入的值當做字符串的形式,eg:select id,name,age from student where id =#{id},當前端把id值1,傳入到後臺的時候,就相當於 select id,name,age from student where id ='1'.

 2 $是將傳入的數據直接顯示生成sql語句,eg:select id,name,age from student where id =${id},當前端把id值1,傳入到後臺的時候,就相當於 select id,name,age from student where id = 1.

 3 使用#可以很大程度上防止sql注入。(語句的拼接)

 4 但是如果使用在order by 中就需要使用 $.

 5 在大多數情況下還是經常使用#,但在不同情況下必須使用$. 

我覺得#與的區別最大在於:#{} 傳入值時,sql解析時,參數是帶引號的,而的區別最大在於:#{} 傳入值時,sql解析時,參數是帶引號的,而{}穿入值,sql解析時,參數是不帶引號的。

一 : 理解mybatis中 $與#

    在mybatis中的$與#都是在sql中動態的傳入參數。

    eg:select id,name,age from student where name=#{name}  這個name是動態的,可變的。當你傳入什麼樣的值,就會根據你傳入的值執行sql語句。

二:使用$與#

   #{}: 解析爲一個 JDBC 預編譯語句(prepared statement)的參數標記符,一個 #{ } 被解析爲一個參數佔位符 。

   ${}: 僅僅爲一個純碎的 string 替換,在動態 SQL 解析階段將會進行變量替換。

  name-->cy

 eg:  select id,name,age from student where name=#{name}   -- name='cy'

       select id,name,age from student where name=${name}    -- name=cy

Mybatis @param使用場景

請參考如下博客

https://blog.csdn.net/u012702547/article/details/96963374

總結:

1. Mybatis在解析mapper.xml文件時,針對通過#{}引用的參數,是通過?佔位符和PreparedStatement.setObject()方式來組裝sql語句的,可以方式sql注入。比如傳入的參數 username="xyz", password="nihao' or '1'='1"下邊的方式可以可以防止sql注入。

String sql = "delete from user where username = ? and password = ?";
            PreparedStatement pstmt = con.prepareStatement(sql);
            //添加參數
            pstmt.setString(1, username);
            pstmt.setString(2, password);
            //進行查詢
            rs = pstmt.executeQuery();

而通過${}引用的參數,是直接通過字符串拼裝的方式構造最終執行的sql語句。就像下邊這樣:

stmt =con.createStatement();
            String sql = "delete from garytb where username = '"+username+"' and password = '"+password+"'";
            rs = stmt.executeQuery(sql);

2. #{}如果是字符串類型,會自動加上引號。而${}不會,mybatis底層只是會做一個字面量的拼接。

    //username="xyz"
    <select id="test" >
        SELECT * FROM USERS WHERE USERNAME = #{userName};
    </select>

比如上邊的mapper.xml文件中定義的語句,最後拼裝的結果是

SELECT * FROM USERS WHERE USERNAME ='xmy';

而如果上邊的參數替換成${userName},則效果就變成了:

SELECT * FROM USERS WHERE USERNAME =xmy;

執行的時候就會報錯。

3. 有的時候參數是表明或列明時,拼接後的字符串表明和列明肯定不能有引號,這時${}就派上用場了。需要注意的是,使用${}時,定義mapper接口時,需要在參數名字前使用@param。

@Mapper
public interface UserMapper {
    List<User> getAllUsers(@Param("order_by")String order_by);
}

<select id="getAllUsers" resultType="xxx.User">
    select * from user order by ${order_by} desc
</select>

再比如,我們希望使用select  in()語句,這個時候也是隻能使用${}。

@Mapper
public interface UserMapper {
    List<User> getAllUsers(@Param("order_by")String userNames);
}

//userNames="'Bob','Tom','Jerry'";
<select id="getAllUsers" resultType="xxx.User">
    select * from user where userName in(${userNames})
</select>

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章