兄弟們好,今天我們來聊一下動态
SQL
什麼是動态的
SQL
呢?顧名思義,
SQL
可以動态的更新,在我們業務中往往會根據某些條件對資料庫中的資料進行一些特殊的更新,而在不是用動态
SQL
技術的時候,這種需求的實作往往很複雜,同時也很難維護。在
MyBatis
中提供了動态
SQL
的支援,他依靠
OGNL
表達式實作了一些條件的判斷和資料的疊代。下面我們一起來聊聊
MyBatis
中的動态
SQL
。
1. 條件語句
1.1 if
if
語句和我們在
Java
中的
if
相同,也是根據條件來執行代碼塊中的内容。我們來看一下它的文法規則。
上述代碼分析:
-
标簽中的if
屬性中的語句如果為test
則執行标簽内的語句。true
如果條件為真,則語句為
否則為
我們再來看一下這種情況:
上述代碼分析:
如果
test
條件為真,則語句為:
這個時候的語句就違背了
SQL
的文法規則,是以在單獨使用
if
語句的時候,往往需要添加如下代碼
上述代碼分析:
條件為真語句為:
注意:
-
語句可以多次出現,也就是可以進行多重if
判斷if
1.2 choose、when、otherwise
這個語句類似于我們
Java
中的
IF ELSE
語句。看它的文法
上述代碼分析:
- 執行
中的腳本内容choose
- 首先判斷第一個
中的when
是否為真,則之後的在test
中的腳本都不會執行,相當于直接choose
break
- 如果第一個
的結果為when
,則進入第二個;false
- 如果第二個
的結果也為when
,則直接執行false
中的内容otherwise
我們看一下場景的
SQL
第一個
when
為真
第二個
when
為真
前兩個都為假
同樣,這個語句也會出現上面
if
所出現的當
where
後面沒有語句的時候,直接使用條件判斷語句,會出現
SQL
的文法錯誤現象,也需要通過
1=1
來解決。
1.3 CASE WHEN THEN ELSE END
這個語句不是由
MyBatis
提供的,而是原聲的
SQL
語句,它可以簡化我們很多的操作,租用有點類似于
Switch
。
上述代碼分析:
- 首先它會使用
後面的變量和CASE
後面的變量進行比較(這個地方類似于一個WHEN
語句)switch
- 如果第一個
比對,則直接傳回WHEN
以後的值THEN
- 如果
中沒有比對的直接傳回WHEN
中的值,最後以ELSE
結束END
我們再來看它的另一種寫法,這個寫法類似于一個
IF ELSE
上述代碼分析:
- 直接在
語句中書寫判斷式的語句,和WHEN
相同,也是僅僅執行一個分支if ELSE
1.4 TRIM WHERE SET
在上面聊
if
和
choose,when,otherwise
的時候,我們發現了一個問題,當在
where
關鍵字後面不存在已有條件的時候,會出現
SQL
語句文法出錯的情況,我們的解決辦法是加上
1=1
讓一個條件恒成立。不過
MyBatis
給我們提供了一種解決這種情況的更好的方案。
我們來看一下它是怎麼做的?
解析上述代碼:
-
元素隻有在子元素傳回内容的時候才會插入一個where
子句。where
- 如果傳回的子句開頭是
或者AND
的時候,OR
元素也會将他們全部去掉where
上面是通過
where
元素實作的需求,下面我們看一下通過
trim
元素實作
分析上述代碼:
-
标簽的trim
字首會在子元素有傳回的時候傳回一個該屬性的屬性值prefix
-
屬性,會将子句傳回的結果中開頭為屬性值的元素移除,通過管道符prefixOverrides
進行分割(注意空格)|
這個時候還需要和大家提一個元素
set
,它常常用于更新操作中,配合條件語句使用,我們來看一下它的用法
分析上述代碼:
- 和
類似,它也是在子句有傳回的時候才會添加一個where
語句SET
同樣它也可以寫成
trim
的方式
2. 循環語句
循環語句隻有一個
foreach
,這個名字非常熟悉,幾乎所有的語言中都這個名字。我們來看一下它的文法
分析上述代碼:
- 當
是清單的時候collection
-
代表清單中的元素item
-
代表正在疊代的下标index
-
- 當
是映射的時候collection
-
代表的是item
value
-
代表index
key
-
-
代表了疊代最開始的符号open
-
代表了每一個疊代元素之間的分割符号separator
-
代表了結束符号close
當
collection
是
map
的時候
分析上述代碼:
- 上述代碼使用了
文法,進行了一個判斷篩選CASE WHEN THEN ELSE END
3. 注解使用動态SQL
現在我們業務開發一般都是基于注解的驅動開發,是以需要在注解中直接書寫動态
SQL
,
MyBatis
提供了一個
script
标簽幫助我們來注解中書寫動态
SQL
文法和
xml
類似,就通過一個
scirpt
标簽進行了包裹而以
4. 使用Java代碼建構SQL
Mybatis
提供了一個
SQL
建構器,幫助我們可以通過
Java
代碼建構一條
SQL
我們來看一下案例
分析上述代碼;
- 這是通過鍊式文法建構的
SQL
-
後面預設是WHERE
,如果想要使用AND
,需要在後面寫明OR
(如上例)OR()
-
- 通過
注解,調用@SelectProvider
中定義的UserSqlProvider
SQL
再來看一下另一種寫法
分析上述代碼:
- 和上面的相比,它使用了匿名内部類的方式,通過代碼塊直接調用内部的方法建構
,是以可以書寫SQL
語句,進行條件判斷。if
好啦,關于動态
SQL
的内容就隻有這些了,兄弟們,下期見
往期原創好文推薦:
lsp都要看的記憶體模型
抽絲剝繭——狀态設計模式
抽絲剝繭——模闆方法設計模式
抽絲剝繭——疊代器設計模式
ThreadLocal為啥要用弱引用?不知道