1. 程式人生 > >mybatis中的${}與#{}的理解

mybatis中的${}與#{}的理解

破壞 字段名 數據 from 兩種 opera 使用場景 any operator

  mybatis作為目前java較為常使用的orm框架,其中動態sql的參數的註入有${}與#{兩種形式,下面來介紹一下他們之間的區別,

  #{}作為參數註入的方式時,從表象上來看,是在參數上添加了一個“”號,從實際執行情況來看,他其實是對原sql語句進行了預編譯,留下的參數位置作為一個“”坑“,使用預編譯有以下幾個好處,

1、效率性,數據庫在處理SQL語句時都有一個預編譯的過程,而預編譯對象就是把一些格式固定的SQL編譯後,存放在內存池中即數據庫緩沖池,當我們再次執行相同的SQL語句時就不需要預編譯的過程了,只需DBMS運行SQL語句。所以當你需要執行該sql多次的時候,將會大大降低運行時間,特別是的大型的數據庫中,它可以有效的也加快了訪問數據庫的速度。

2、防止sql註入,防止了 userName = "1‘ OR ‘1‘=‘1";這種萬能密碼,或者"SELECT * FROM users WHERE name = ‘any_value‘ and pw = ‘‘; DROP TABLE users"這種破壞性的參數註入手段

  ${}作為參數註入方式時,從表象上來看,將參數拼接進sql中,未加“”號,這種方式其實質上就是作了一個字符串的拼接,所以第一個問題是他需要每次都編譯一個新的sql,而在數據庫的處理中,編譯sql是一個比較耗費資源的事,這就影響了效率,不方便復用。

  比較兩種方式,#{}是先編譯再註入參數,而${}是先拼接字符串,然後在編譯,所以我們推薦的能用#{}就用#{},當然,如果#{}能解決一切問題也沒有${}存在的價值了,${}也存在其必要的使用場景,如變量的位置處於表名,字段名時,使用#{}無法完成拼接功能的,然後還有一種情景,在條件為in 多個參數拼接的字符作為條件時(如 in "2,3,4"),需要使用${}強行憑借,因為若使用了#{},實際判斷的是該字段是否在(2,3,4)這一個字符串中,這其實也是為了防止sql註入。

mybatis中的${}與#{}的理解