代碼直接放在Github倉庫【 https://github.com/Damaer/Myb... 】,可直接運行,就不佔篇幅了。
[TOC]git
1.#{}佔位符能夠用來設置參數,若是傳進來的是基本類型,也就是(string
,long
,double
,int
,boolean
,float
等),那麼#{}
裏面的變量名能夠隨意寫,什麼abc
,xxx
等等,這個名字和傳進來的參數名能夠不一致。github
2.若是傳進來的是pojo
類型,那麼#{}
中的變量名必須是pojo
的屬性名,能夠寫成屬性名
,也能夠寫屬性名.屬性名
。sql
參數是int
,不須要設置parameterType
:apache
<delete id="deleteStudentById" > delete from student where id=#{XXXdoukeyi} </delete>
parameterType
是pojo
類,若是使用pojo
類型做爲參數,那麼必須提供get
方法,也就是框架在運行的時候須要經過反射根據#{}
中的名字,拿到這個值放到sql
語句中,若是佔位符中的名稱和屬性不一致,那麼報ReflectionException
。安全
<insert id="insertStudent" parameterType="Student"> insert into student(name,age,score) values(#{name},#{age},#{score}) </insert>
3.#{}佔位符不能解決的三類問題:框架
動態表名不能夠用#{} :Select * from #{table}
動態列名不能夠用#{} : select #{column} from table
動態排序列不能夠用#{} : select * from table order by #{column}
注意:不能這樣寫:學習
<insert id="insertStudent" parameterType="Student"> insert into student(name,age,score) values(#{Student.name},#{Student.age},#{Student.score}) </insert>
不然會報一個錯誤(會將Student
當成一個屬性),因此咱們類名就直接省略不寫就能夠了:.net
### Cause: org.apache.ibatis.reflection.ReflectionException: There is no getter for property named 'Student' in 'class bean.Student'
1.若是傳進來的是基本類型,也就是(string
,long
,double
,int
,boolean
,float
等),那麼#{}
裏面的變量名必須寫value
。code
<delete id="deleteStudentById" > delete from student where id=${value} </delete>
2.若是傳進來的是pojo
類型,那麼#{}
中的變量名必須是pojo
的屬性名,能夠寫成屬性名
,也能夠寫屬性名.屬性名
。可是因爲是拼接的方式,對於字符串咱們須要本身加引號。xml
<insert id="insertStudent" parameterType="Student"> insert into student(name,age,score) values('${name}',${age},${score}) </insert>
與上面同樣,不能將類名寫進來:
<!--這是錯誤的--> <insert id="insertStudent" parameterType="Student"> insert into student(name,age,score) values('${Student.name}',${Student.age},${Student.score}) </insert>
3.${}佔位符是字符串鏈接符,能夠用來動態設置表名,列名,排序名
動態表名 :Select * from ${table}
動態列名 : select ${column} from table
動態排序 : select * from table order by ${column}
4.${}能夠做爲鏈接符使用,可是這樣的方式是不安全的,很容易發生sql注入問題,sql注入問題能夠參考https://blog.csdn.net/aphysia...:
<select id="selectStudentsByName" resultType="Student"> select id,name,age,score from student where name like '%${value}%' </select>
- 1.能使用
#{}
的時候儘可能使用#{}
,不使用${}
。- 2.
#{}
至關於jdbc
中的preparedstatement
(預編譯),${}
是直接使用裏面的值進行拼接,若是解釋預編譯和直接拼接,我想能夠這麼理解預編譯:好比將一個#{name}
傳進來,預編譯是先將sql
語句編譯成爲模板,也就是我知道你要幹什麼,假設這個sql
是要查詢名字爲xxx
的學生信息,那不管這個xxx
裏面是什麼信息,我都只會去根據名字這一列查詢,裏面不管寫的是什麼,都只會當作一個字符串,這個類型在預編譯的時候已經定義好了。- 3.
${}
就不同,是將語句拼接以後才肯定查詢條件/類型的,那麼就會有被注入的可能性,有些人故意將名字設置爲刪除條件,這時候sql
就變成刪除操做了。- 因此咱們通常相似模糊查詢都是用
#{}
拼接
<select id="selectStudentsByName" resultType="Student"> select id,name,age,score from student where name like '%' #{name} '%' </select>
- 可是對於
order by
咱們是用不了#{}
的,由於用了這個就會被自動轉換成字符串,自動加引號,這樣語句就不生效了。
<select id="selectStudentsByName" resultType="Student"> select id,name,age,score from student order by #{column} </select> <!--編譯出來的結果以下:--> select * from table order by 'column'
那咱們須要怎麼處理呢?咱們只能使用${}
,MyBatis
不會修改或轉義字符串。這樣是不安全的,會致使潛在的SQL
注入攻擊,咱們須要本身限制,不容許用戶輸入這些字段,或者一般自行轉義並檢查。因此這必須過濾輸入的內容。
【做者簡介】:
秦懷,公衆號【秦懷雜貨店】做者,技術之路不在一時,山高水長,縱使緩慢,馳而不息。這個世界但願一切都很快,更快,可是我但願本身能走好每一步,寫好每一篇文章,期待和大家一塊兒交流。
此文章僅表明本身(本菜鳥)學習積累記錄,或者學習筆記,若有侵權,請聯繫做者覈實刪除。人無完人,文章也同樣,文筆稚嫩,在下不才,勿噴,若是有錯誤之處,還望指出,感激涕零~