Mybatis【9】-- Mybatis佔位符#{}和拼接符${}有什麼區別?

代碼直接放在Github倉庫【 https://github.com/Damaer/Myb... 】,可直接運行,就不佔篇幅了。

[TOC]git

1.#{}佔位符

1.#{}佔位符能夠用來設置參數,若是傳進來的是基本類型,也就是(string,long,double,int,boolean,float等),那麼#{}裏面的變量名能夠隨意寫,什麼abc,xxx等等,這個名字和傳進來的參數名能夠不一致。github

2.若是傳進來的是pojo類型,那麼#{}中的變量名必須是pojo的屬性名,能夠寫成屬性名,也能夠寫屬性名.屬性名sql

參數是int,不須要設置parameterTypeapache

<delete id="deleteStudentById" >
    delete from student where id=#{XXXdoukeyi}
</delete>

parameterTypepojo類,若是使用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'

2.${}拼接符

1.若是傳進來的是基本類型,也就是(string,long,double,int,boolean,float等),那麼#{}裏面的變量名必須寫valuecode

<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>

3.#{}與${}區別

  • 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注入攻擊,咱們須要本身限制,不容許用戶輸入這些字段,或者一般自行轉義並檢查。因此這必須過濾輸入的內容。

【做者簡介】
秦懷,公衆號【秦懷雜貨店】做者,技術之路不在一時,山高水長,縱使緩慢,馳而不息。這個世界但願一切都很快,更快,可是我但願本身能走好每一步,寫好每一篇文章,期待和大家一塊兒交流。

此文章僅表明本身(本菜鳥)學習積累記錄,或者學習筆記,若有侵權,請聯繫做者覈實刪除。人無完人,文章也同樣,文筆稚嫩,在下不才,勿噴,若是有錯誤之處,還望指出,感激涕零~

相關文章
相關標籤/搜索