您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關MyBatis動態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))
定義接口方法
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
標簽。
將上面的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
標簽中的 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}
有時我們不想應用到所有的條件語句,而只想從中擇其一項。針對這種情況,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 標簽用于 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 標簽可以迭代生成一系列值
*用于 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的示例就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。