做者 : Stanley 羅昊sql
【轉載請註明出處和署名,謝謝!】數據庫
寫在前面:mybatis
*本章節適合有Mybatis基礎者觀看*spa
我如今寫一個查詢所有的sql語句,這個對各位來講,想必應該是很是簡單,我舉個例子:code
select * from studnet //查詢所有
我如今需求又變了。我如今要根據年齡進行查詢了,那是否是也依然很簡單:xml
select * from student where age = #{age} //根據年齡查詢學生
那麼,我如今再來一個需求,根據年齡跟姓名來查:對象
select * from student where age = #{age} and name=#{name};
可是,咱們仔細發現,我剛纔在寫sql語句,就須要複製粘貼,那也就意味着,在這以上的sql語句是重複的,也就是說三個語句裏,查詢的都是同一張表,只不過加了一些條件;blog
所以,我沒有必要寫三次,其實咱們寫一次就夠了;開發
若是使用動態sql來實現的話,就很是方便,好比:class
我第一次使用的時候,僅使用select * from student 僅僅的查詢所有,用於初始化
我第二次再去使用的時候 僅使用 where = age
我第三次再去使用的時候 就成了 where = age and name =name
能夠靈活的控制sql語句,這就是動態sql;
能夠設想一下,若是沒有動態sql,咱們是否是一個功能模塊,就要寫三段sql語句,很顯然讓代碼變的很是臃腫不整潔,效率還低,因此,在正常的企業開發當中,動態sql用點居多!
那麼,到底怎麼實現呢?這個,就用到了mybatis xml文件中的動態標籤了;
首先,咱們須要看一下查詢條件:本次業務涉及到查詢全部、根據學生年齡查詢、根據學生年齡而且根據學生姓名進行查詢;
查詢全部,由於要在頁面初始化中使用,因此頁面加載以後須要展現出來,另外那些條件,就是幾個篩選條件,能夠利用他們知足本身的查詢須要;
如今,咱們就根據以上業務來完成一個動態sql;
在要進行查詢的xml文件中編寫:
<select id = "selectAllorbynameAndage" resultType = "Student"> select * from student where <if test = " name!= null and name!= ' ' ">//若是傳過來的student對象有name屬性,而且該屬性不爲空,便執行次條件 student = #{name} </if> <if test = "age !=null and age != ' ' "> And student = #{age} </if> </select>
講解:
1.if:什麼叫if,就是若是有這麼怎辦,若是沒怎麼怎麼辦,在這裏的意思就是,你如今查的時候,要是傳入了一個名字,那麼,我就根據你傳過來的name進行查詢。
換句話說,若是你沒傳這個字段,那麼是否是就不進入這個判斷了,也就表明你沒寫這個where同樣;
用意:我如今傳過來一個學生對象,若是這個學生對象包含了一個name屬性,且name屬性不爲空,那麼我就要把這個student = #{name}給加上
if後面的test裏面就寫執行條件
2.咱們如今除了name以外,是否是還有可能有age;
根據以上的業務,咱們發現,也是有根據age進行查詢的,那麼,咱們僅需在下面跟上一個if裏面來寫關於age的判決便可;
可是值得注意的是,本次編寫前面須要加上and;
and:爲何在加and呢?
咱們能夠設想一下,目前的sql語句是這樣的:
select * from student where name = #{name}
若是不加and的話,是否是就變成了:
select * from student where name = #{name}age = #{age}
這樣顯然是不對的,sql語法都出錯兩,因此須要在前面加上and,加上and以後就是合法的sql語句了:
select * from student where name = #{name}And age = #{age}
那麼,問題來了,以上寫的那種方案是,name 跟 age 必須所有存在,才能夠生效,一旦不存在,那麼就會報錯,我如今認定這個name時在時不在的狀況;
我舉個例子,本次查詢,僅僅按照age查詢,這個時候,age傳過來了,可是name沒有傳過來,由於我只查詢age,確定只用把age傳過來,這個時候,name拿不到值,就致使了這樣的sql語句:
select * from student where And age = #{age}
這就很明顯,sql語句怎麼可能寫成這樣,這個and就很是使人厭煩,爲何會致使成這樣呢?
還記得咱們寫的一個if標籤嗎?若是name = null and name = ‘ ’,我這條標籤就不去執行,一旦不去執行就變成以上那樣了,本來有name是這樣的:
select * from student where name = #{name}And age = #{age}
你如今name爲空了,那就代表name = #{name}就消失了
這個and你也去不掉它,你一旦去掉了,又會形成另一種sql語法非法,如何解決這個不協調的字段呢?
有兩種解決方案;
第一種:
<select id = "selectAllorbynameAndage" resultType = "Student"> select * from student where 1 = 1 <if test = " name!= null and name!= ' ' ">//若是傳過來的student對象有name屬性,而且該屬性不爲空,便執行次條件 And student = #{name} </if> <if test = "age !=null and age != ' ' "> And student = #{age} </if> </select>
我把studnt = name前面也加了一個and,可是這樣作會致使本次sql語句不成立,不要緊,我在where後面加了一個 1 = 1,就表明永遠成立,也就是強制讓數據庫認下這個and;
第二種【最佳/推薦】:
<select id = "selectAllorbynameAndage" resultType = "Student"> select * from student <where> <if test = " name!= null and name!= ' ' ">//若是傳過來的student對象有name屬性,而且該屬性不爲空,便執行次條件 And student = #{name} </if> <if test = "age !=null and age != ' ' "> And student = #{age} </if> </where> </select>
如今呢,咱們直接用where標籤把sql包裹,把主查詢後面的where就刪掉,由於已經不須要了,那麼加上這個where標籤後,sql變成什麼樣子了呢?
select * from student <where> and name = #{name}and age = #{age}
這樣的sql語句看似是否是像是那種有問題的sql語句,由於在where後面就有and,可是沒關心,不用管,這個<where>標籤是智能的,它會自動處理第一個and,不會處理第二個;
什麼意思呢?就是本次查詢,若是你須要這個and,那麼我就給你加上,若是你不須要這個and,我就不給你加,很顯然,本次查詢不須要這個and,因此就沒給你加;
這個時候,你把第一個and給刪了,再去執行,你會發現跟沒刪同樣,若是你加上這個and,你就會發現,跟沒加同樣,就是這麼智能,很是便捷;
可是,若是你把第二個或日後的and刪了,就會出問題了,由於它只會幫你處理第第一個and;
因此,原理是這樣的:
剛纔我說了,若是沒有name,那麼第一個if就會消失,緊接着,age是否是就頂替name了,那麼age就是第一個了
<select id = "selectAllorbynameAndage" resultType = "Student"> select * from student <where> <if test = "age !=null and age != ' ' "> And student = #{age} </if> </where> </select>
那麼這個智能where標籤恰到好處的把第一個and給消掉了,從而完成了根據age查詢;
瞭解以上概念後,咱們就把上面的業務給所有寫完吧,若是age跟name均不爲空,那麼我就根據這兩個進行查詢;
<select id = "selectAllorbynameAndage" resultType = "Student"> select * from student <where> <if test = " name!= null and name!= ' ' ">//若是傳過來的student對象有name屬性,而且該屬性不爲空,便執行次條件 And student = #{name} </if> <if test = "age !=null and age != ' ' "> And student = #{age} </if> <if test = "age ! = null and age !=' ' And name !=null and name ! = ' ' "> And student = #{name} And student = #{age} </if> </where> </select>