【mybatis】從一個錯誤,看mybatis中的#和$的區別


事情的發展是這樣的:

  因為一個需求,需要在java中拼接出一個完整的sql語句,然后將整條sql語句傳遞給mybatis執行。

 

mapper.java是這樣的:

int insertMaster(WorksheetMasterSQLBean masterBean);

這個對象是:

public class WorksheetMasterSQLBean {

    private Long id;

    private String masterInsertSql;

【就是用

masterInsertSql 字段裝了一下SQL,因為要在insert執行后返回自增ID的緣故,所以把SQL裝在一個對象的屬性中。主要就是想用一個bean的id取接收一下自增id.

無所謂啦,往下看】【mybatis的insert返回自增id

 

mapper.xml是這樣的:

【把sql放進insert標簽中,執行】

  <insert id="insertMaster" parameterType="com.lqjava.daywork.api.beans.WorksheetMasterSQLBean" useGeneratedKeys="true" keyProperty="id">
        #{masterInsertSql}
    </insert>

 

SQL語句是:

【這就是在java中直接拼接好的sql語句】

INSERT INTO   worksheet_data_14    (create_by,create_date,update_by,update_date,`input-number_0`)  VALUES (1,'2019-05-15 12:44:45',1,'2019-05-15 12:44:45','坦桑尼亞' )

 

報錯:

【媽的,報錯了】

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''INSERT INTO 

 

 

原因:

1.到了這里,就思考這個問題。

我傳入的參數,也就是String類型的sql語句,明明就是上面那個,為什么執行完了會報錯。而且錯誤提示,就是在

''INSERT INTO

這個地方?

懷疑是不是在java中sql拼接的時候,自己多搞出來幾個單引號在前面呀【或者空格之類的】

 

2.仔細的debug了幾次程序,發現,java中拼接出來的sql語句完全沒有任何問題。

既沒有加單引號,又沒有前后空格,也沒有使用關鍵字這一說。

那問題只能在將 sql送進mybatis之后,發生的問題了。

 

3.這里就說到了mybatis的$#的區別

首先:

  mybatis拼接sql時候,使用${參數} 和 #{參數} 都可以接受參數

第二:

例如:age = 1

select * from user where age = #{age};
select * from user where age = ${age};

 

如果使用${參數},那就是將參數原原本本的進行字符串的替換,不會做任何過多的處理。

看一下${}對上面的預編譯的結果為

select * from user where age = 1;

 

如果使用#{參數},則會在預編譯階段生成占位符?,實際值的替換是在DBMS中進行的。

看一下#{}對上面的預編譯的結果為

select * from user where age = ?;

 

4.那看到了$和#的區別,為什么兩個都可以在mybatis中使用?各自的優勢何在

  1》#{},預編譯生成占位符?,實際的參數值替換在DBMS中,根據參數類型,是否添加''單引號

    第一個優勢:

      省時省力。那預編譯的語句,會被緩存下來,下次相同的語句執行,不用編譯,直接就可以拿到數據庫操作,直接在數據庫中進行參數替換即可。省時省力。

    第二個優勢:

      防止SQL注入。如果像我上面的使用情況,我給占位符的地方傳入的並不是一個值,而是一個;delete的刪除語句,那直接傳入數據庫中,有了占位符替換的過程,會自動給string類型的加上''單引號在前后,這樣就出現了上面我的錯誤。執行不了。

 

  2》${},直接進行字符串的替換

    那按上面那么說,${}就完全沒有優勢可言了么?

    不是的,就像上面的錯誤一樣,這個時候就需要${}出馬,才能直接將完整的sql語句替換。不會添加任何的''在前后。

    所以,像是如果mybatis中寫了sql,但是表名是動態的,則需要${}。因為表名是不需要加''在前后的。

 

5.對於mybatis中#和$的總結

  #{}是占位符號

  ${}是sql拼接符號

 

 

解決方案:

替換mapper.xml中的#為$,即可解決問題:

  <insert id="insertMaster" parameterType="com.lqjava.daywork.api.beans.WorksheetMasterSQLBean" useGeneratedKeys="true" keyProperty="id">
        ${masterInsertSql}
    </insert>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM