1. 程式人生 > >Mybatis對映檔案Mapper.xml中#和$的區別

Mybatis對映檔案Mapper.xml中#和$的區別

關於Mapper.xml對映語句中什麼時候用"#"什麼時候用"$",已經有很多人做過總結,我最近在寫專案時仍然遇到了一點問題,所以在這裡結合專案文件和案例,再做一下總結,也作為個人的筆記,在這裡再總結下。

一、先看一下在mybatis api中關於"#"和"$"的描述

1、"#"

圖 1來自於mybatis api “Mapper XML檔案”章節,   簡單來說"#"在編譯時使用"?"佔位符標記,可以有效防止引數注入,相當於我們使用JDBC操作時的PreparedStatement。

                                                                                                 圖1

2、"$" 

 圖2同樣來自於mybatis api “Mapper XML檔案”章節,意思是直接把引數拼接到SQL中執行相當於JDBC操作時的Statement

                                                                                          圖2

二、結合案例具體說明"#"和"$" 的區別。

1、引數作為非SQL關鍵字傳遞

 <insert id="addUser" parameterType="User">
      insert into users values(default, ${username}, ${password}, ${photo});
 </insert>

該語句執行報錯,通過日誌分析,

[19:32:41.422] [DEBUG] org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:139) ==>  Preparing: insert into users values(default, test, 123456, c9ae464f-348d-491d-a162-a9624c99f73b); 
[19:32:41.479] [DEBUG] org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:139) ==> Parameters: 

Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'test' in 'field list'
; bad SQL grammar []; nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'test' in 'field list'] with root cause

從這裡可以看到,這裡直接把獲取到的引數拼接到了SQL中,資料庫把引數當成了列名,資料庫欄位設定的都是varchar型別,需要把列值加上"",方可執行成功,如下:

<insert id="addUser" parameterType="User">
        insert into users values(default, "${username}", "${password}", "${photo}");
</insert>

日誌如下:

[19:42:30.616] [DEBUG] org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:139) ==>  Preparing: insert into users values(default, "test", "123456", "85ec0040-46dc-4a92-b995-7ed84ece2f28"); 
[19:42:30.698] [DEBUG] org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:139) ==> Parameters: 
[19:42:30.755] [DEBUG] org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:139) <==    Updates: 1

或者把"$"改成"#"

<insert id="addUser" parameterType="User">
        insert into users values(default, #{username}, #{password}, #{photo});
 </insert>

2、引數作為關鍵字傳遞,比如查詢條件全是由引數拼接的,只是用一條SQL,有時要按name列查,有時要按age列查

<select id="selectUser" parameterType="User" resultType="User">

      select * from users where ${columnName}  ${condition}  #{columnValue}

</select>

SQL1:select * from users where username = "test";

SQL2:select * from users where userage like "%2";

因為列名和關係條件是關鍵字,是用"$",列值是非關鍵字,使用"#"。

三、總結

1、關鍵字作為引數,使用"$",兩邊不加""。

2、非關鍵字作為引數,使用"#"防注入。

其他情況優先使用"#"