共計 6331 個字符,預計需要花費 16 分鐘才能閱讀完成。
自動寫代碼機器人,免費開通
這篇文章將為大家詳細講解有關 MyBatis 動態 SQL 的示例,丸趣 TV 小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。
動態 SQL
MyBatis 的強大特性之一便是它的動態 SQL。如果你有使用 JDBC 或其它類似框架的經驗,你就能體會到根據不同條件拼接 SQL 語句的痛苦。例如拼接時要確保不能忘記添加必要的空格,還要注意去掉列表最后一個列名的逗號。利用動態 SQL 這一特性可以徹底擺脫這種痛苦。
雖然在以前使用動態 SQL 并非一件易事,但正是 MyBatis 提供了可以被用在任意 SQL 映射語句中的強大的動態 SQL 語言得以改進這種情形。
動態 SQL 元素和 JSTL 或基于類似 XML 的文本處理器相似。在 MyBatis 之前的版本中,有很多元素需要花時間了解。MyBatis 3 大大精簡了元素種類,現在只需學習原來一半的元素便可。MyBatis 采用功能強大的基于 OGNL 的表達式來淘汰其它大部分元素。
準備
首先創建 User 實體類
public class User {
private Integer id;
private String username;
private String userEmail;
private String userCity;
private Integer age;}
創建 user 表
CREATE TABLE user ( id int(11) NOT NULL AUTO_INCREMENT,
username varchar(255) DEFAULT NULL,
user_email varchar(255) DEFAULT NULL,
user_city varchar(255) DEFAULT NULL,
age int(11) DEFAULT NULL,
PRIMARY KEY (id))
if
定義接口方法
public List User findByUser(User user);
接口對應的 Mapper.xml 定義如下所示
select id= findByUser resultType= com.example.mybatis.entity.User
select
id, username, user_email userEmail, user_city userCity, age
from user
where if test= username != null and username !=
username = #{username} /if
if test= userEmail != null and userEmail !=
and user_email = #{userEmail} /if
if test= userCity != null and userCity !=
and user_city = #{userCity} /if /select
如果 if 標簽上的 test 為 true,那么 if 標簽里面的 SQL 語句將會被拼接。
如果 username、userEmail、userCity 都不為空,那么 SQL 將會拼接成如下所示
select id, username, user_email userEmail, user_city userCity, age
from user where username = ?
and user_email = ? and user_city = ?
如果只有 username 不為空,那么 SQL 將會拼接成如下所示
select id, username, user_email userEmail, user_city userCity, age
from user where username = ?
但是這種方式存在一個缺點,假設此時 username 為空,userEmail、userCity 都不為空。
我們來分析動態 SQL 代碼,現在沒有給 username 賦值,即 username==null,所以“username=#{username}”這段代碼不會添加到 SQL 語句中,那么最終拼接好的動態 SQL 是這樣的:
select id, username, user_email userEmail, user_city userCity, age
from user where and user_email = ? and user_city = ?
where 后面直接跟 and,很明顯的語法錯誤,此時應該把緊跟在 where 后面的 and 刪掉。為了解決這個問題,可以使用 where 標簽。
where
將上面的 SQL 改成如下所示
select id= findByUser resultType= com.example.mybatis.entity.User
select
id, username, user_email userEmail, user_city userCity, age from user
where
if test= username != null and username !=
username = #{username}
/if
if test= userEmail != null and userEmail !=
and user_email = #{userEmail}
/if
if test= userCity != null and userCity !=
and user_city = #{userCity}
/if
/where
/select
如果 where 標簽里面的 if 標簽有滿足條件的,那么 where 標簽就會被拼接成 where 語句,若 if 標簽拼接的 SQL 最前面有 and 語句,那么這個 and 將會被刪除。使用這種方法,會自動刪除 SQL 中不需要的關鍵字,所以一般 if 標簽和 where 標簽會組合起來使用。
trim
trim 標簽中的 prefix 和 suffix 屬性會被用于生成實際的 SQL 語句,會和標簽內部的語句拼接。
如果語句的前面或后面遇到 prefixOverrides 或 suffixOverrides 屬性中指定的值,MyBatis 會自動將它們刪除。在指定多個值的時候,別忘了每個值后面都要有一個空格,保證不會和后面的 SQL 連接在一起。
prefix:給拼接的 SQL 語句加一個前綴
suffix:給拼接的 SQL 語句加一個后綴
prefixOverrides:拼接的 SQL 語句前面遇到 prefixOverrides,MyBatis 會自動將它們刪除
suffixOverrides:拼接的 SQL 語句后面遇到 suffixOverrides,MyBatis 會自動將它們刪除
下面使用 trim 標簽來實現 where 標簽的功能
select id= findByUser resultType= com.example.mybatis.entity.User
select
id, username, user_email userEmail, user_city userCity, age
from user trim prefix= where prefixOverrides= and
if test= username != null and username !=
username = #{username} /if
if test= userEmail != null and userEmail !=
and user_email = #{userEmail} /if
if test= userCity != null and userCity !=
and user_city = #{userCity} /if
/trim
/select
如果 username 為空,userEmail 和 userCity 不為空,那么 if 標簽拼接的 SQL 語句如下所示
and user_email = #{userEmail} and user_city = #{userCity}
因為 trim 標簽設置了 prefixOverrides=”and”,而上面的 SQL 前面有 and 語句,所以需要將上面的 and 語句刪掉,又因為 trim 標簽設置了 prefix=”where”,所以需要在拼接的 SQL 語句前面加一個 where 語句
最后 trim 標簽的 SQL 語句被拼接成如下所示
where user_email = #{userEmail} and user_city = #{userCity}
choose
有時我們不想應用到所有的條件語句,而只想從中擇其一項。針對這種情況,MyBatis 提供了 choose 元素,它有點像 Java 中的 switch 語句。
select id= findByUser resultType= com.example.mybatis.entity.User
select
id, username, user_email userEmail, user_city userCity, age
from user where
choose
when test= username != null and username !=
username = #{username} /when
when test= userEmail != null and userEmail !=
and user_email = #{userEmail} /when
when test= userCity != null and userCity !=
and user_city = #{userCity} /when
/choose
/where
/select
set
set 標簽用于 Update 操作,會自動根據參數選擇生成 SQL 語句。
接口定義如下
public int updateUser(User user);
接口對應的 Mapper.xml 定義如下所示
update id= updateUser parameterType= com.example.mybatis.entity.User
update user set
if test= username != null and username !=
username=#{username}, /if
if test= userEmail != null and userEmail !=
user_email=#{userEmail}, /if
if test= userCity != null and userCity !=
user_city=#{userCity}, /if
if test= age != null
age=#{age} /if
/set
where id=#{id} /update
foreach
foreach 標簽可以迭代生成一系列值
* 用于 SQL 的 in 語句 *
接口定義如下所示
public List User getUsersByIds(List Integer ids);
接口對應的 Mapper.xml 定義如下所示
!--
collection: 指定要遍歷的集合
默認情況下
如果為 Collection 類型的,key 為 collection; 如果為 List 類型的,key 為 list
如果是數組類型,key 為 array
可以通過 @Param(ids) 來指定 key
item: 將當前遍歷的元素賦值給指定的變量
open: 給遍歷的結果添加一個開始字符
close: 給遍歷的結果添加一個結束字符
separator: 每個元素之間的分隔符
-- select id= getUsersByIds
resultType= com.example.mybatis.entity.User
select * from user
where id in foreach collection= list item= id open= ( close=) separator= ,
#{id} /foreach /select
用于批量插入
接口定義如下所示
public int addUserList(List User users);
接口對應的 Mapper.xml 定義如下所示
insert id= addUserList
parameterType= com.example.mybatis.entity.User
insert into user
(username, user_email, user_city, age)
values foreach item= user collection= list separator= ,
(#{user.username}, #{user.userEmail}, #{user.userCity}, #{user.age}) /foreach /insert !-- 返回自增主鍵 -- insert id= addUserList
parameterType= com.example.mybatis.entity.User
useGeneratedKeys= true
keyProperty= id
insert into user
(username, user_email, user_city, age)
values foreach item= user collection= list separator= ,
(#{user.username}, #{user.userEmail}, #{user.userCity}, #{user.age}) /foreach /insert !-- 還可以這樣寫 -- !--
這種方式需要數據庫連接屬性設置 allowMultiQueries=true
這種分號分隔多個 SQL 還可以用于其他的批量操作,如修改、刪除
-- insert id= addUserList
parameterType= com.example.mybatis.entity.User
foreach item= user collection= list separator=
insert into user
(username, user_email, user_city, age)
values
(#{user.username}, #{user.userEmail}, #{user.userCity}, #{user.age}) /foreach /insert !-- 如果是 Oracle 數據庫,則需要這樣寫 -- insert id= addUserList
parameterType= com.example.mybatis.entity.User
foreach item= user open= begin close= end; collection= list
insert into user
(username, user_email, user_city, age)
values
(#{user.username}, #{user.userEmail}, #{user.userCity}, #{user.age}); /foreach /insert
關于 MyBatis 動態 SQL 的示例就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
向 AI 問一下細節
丸趣 TV 網 – 提供最優質的資源集合!