其所有的sql在執行前都會通過數據庫驅動進行預編譯,這樣DBMS就可以不用編譯直接接收參數運行,
而#和$號的區別在預編譯後就能看出來了,#{}預編譯完是佔位符?,而${}預編譯完就是傳進來的參數。
l #{}和${}
#{}表示佔位符?,#{}接收簡單類型的參數時,裏面的名稱可以任意
${}表示拼接符,${}接收簡單類型的參數時,裏面的名稱必須是value
${}裏面的值會原樣輸出,不加解析(如果該參數值是字符串,有不會添加引號)
${}存在sql注入的風險,但是有些場景下必須使用,比如排序後面會動態傳入排序的列名
1)使用#入參,myBatis會生成PrepareStatement並且可以安全地設置參數(=?)的值。因爲sql語句已經預編譯好了,傳入參數的時候,不會重新生產sql語句。安全性高。
2)用$可以會有sql注入的問題:
例如,select * from emp where ename = '用戶名',如果使用$入參,用戶名被傳入例如‘smith or 1 = 1’,那無論ename是否匹配都能查到結果。
3)在特定場景下,例如如果在使用諸如order by '{param}',這時候就可以使用$.
======================================================
MyBatis 的緩存分爲一級緩存
和二級緩存
。
- 一級緩存是 SqlSession 級別的緩存
- 二級緩存是 mapper 級別的緩存,多個 SqlSession 共享
一級緩存
一級緩存是 SqlSession 級別的緩存,是基於 HashMap 的本地緩存。不同的 SqlSession 之間的緩存數據區域互不影響。
一級緩存的作用域是 SqlSession 範圍,當同一個 SqlSession 執行兩次相同的 sql 語句時,第一次執行完後會將數據庫中查詢的數據寫到緩存,第二次查詢時直接從緩存獲取不用去數據庫查詢。當 SqlSession 執行 insert、update、delete 操做並提交到數據庫時,會清空緩存,保證緩存中的信息是最新的。
在sqlsession中有一個數據區域,是map結構,這個區域就是一級緩存區域。一級緩存中的key是由sql語句、條件、statement等信息組成一個唯一值。一級緩存中的value,就是查詢出的結果對象。
MyBatis 默認開啓一級緩存。
二級緩存是 mapper 級別的緩存,同樣是基於 HashMap 進行存儲,多個 SqlSession 可以共用二級緩存,其作用域是 mapper 的同一個 namespace。不同的 SqlSession 兩次執行相同的 namespace 下的 sql 語句,會執行相同的 sql,第二次查詢只會查詢第一次查詢時讀取數據庫後寫到緩存的數據,不會再去數據庫查詢。
MyBatis 默認沒有開啓二級緩存,開啓只需在配置文件中寫入如下代碼:
<settings>
<setting name="cacheEnabled" value="true"/>
</settings>