MyBatis還有一個方便的功能就是動態SQL,可以根據條件智能生成SQL語句。這里的例子全部來自MyBatis文檔。
下面這個例子使用了MyBatis的if元素,在標題不為空的情況下在查詢結果中包含標題的查詢。
<select id="findActiveBlogWithTitleLike" resultType="Blog"> SELECT * FROM BLOG WHERE state = ‘ACTIVE’ <if test="title != null"> AND title like #{title} </if></select>如果需要在多個情況中包含某一個查詢條件。可以向下面這樣,使用choose、when、otherwise。如果使用過JSTL的話,會發現這和JSTL的條件標簽非常類似。
<select id="findActiveBlogLike" resultType="Blog"> SELECT * FROM BLOG WHERE state = ‘ACTIVE’ <choose> <when test="title != null"> AND title like #{title} </when> <when test="author != null and author.name != null"> AND author_name like #{author.name} </when> <otherwise> AND featured = 1 </otherwise> </choose></select>對于下面這個例子,如果state為空,無法生成合法的SQL語句。
<select id="findActiveBlogLike" resultType="Blog"> SELECT * FROM BLOG WHERE <if test="state != null"> state = #{state} </if> <if test="title != null"> AND title like #{title} </if> <if test="author != null and author.name != null"> AND author_name like #{author.name} </if></select>MyBatis自然也有相應的解決辦法。就是使用where標簽改寫。where標簽非常智能。如果標簽內部沒有合適的語句,where標簽就不會生成任何東西,防止出現錯誤語句。
<select id="findActiveBlogLike" resultType="Blog"> SELECT * FROM BLOG <where> <if test="state != null"> state = #{state} </if> <if test="title != null"> AND title like #{title} </if> <if test="author != null and author.name != null"> AND author_name like #{author.name} </if> </where></select>有時候where標簽還不能滿足需求。這時候還可以使用trim標簽進行更高級的定制。trim標簽中的PRefix和suffix屬性會被用于生成實際的SQL語句,會和標簽內部的語句拼接。如果語句的前面或后面遇到prefixOverrides或suffixOverrides屬性中指定的值,MyBatis會自動將它們刪除。在指定多個值的時候,別忘了每個值后面都要有一個空格,保證不會和后面的SQL連接在一起。下面這個例子和where標簽完全等效。
<trim prefix="WHERE" prefixOverrides="AND |OR "> ...</trim>還有一個set標簽用于智能執行更新語句。
<update id="updateAuthorIfNecessary"> update Author <set> <if test="username != null">username=#{username},</if> <if test="passWord != null">password=#{password},</if> <if test="email != null">email=#{email},</if> <if test="bio != null">bio=#{bio}</if> </set> where id=#{id}</update>與它等價的trim標簽如下。
<trim prefix="SET" suffixOverrides=","> ...</trim>還有一個迭代標簽可以生成一系列值,這個標簽主要用于SQL的in語句后面。
<select id="selectPostIn" resultType="domain.blog.Post"> SELECT * FROM POST P WHERE ID in <foreach item="item" index="index" collection="list" open="(" separator="," close=")"> #{item} </foreach></select>bind標簽可以將非OGNL表達式值綁定到其中。下面的例子將結果映射中的值綁定到了OGNL表達式中,從而可以直接使用#{}語法訪問。
有時候需要在java代碼中生成SQL語句。如果我們直接編寫的話會是一件非常麻煩的事情。由于Java不支持跨行字符串,所以我們要么在一行里面寫一個非常非常長的SQL語句,要么用加號拼接出一個笨拙的字符串。MyBatis提供了SQL構造類,我們可以方便的使用這個類構造出SQL語句。
下面這幾個例子同樣來自于MyBatis文檔。SQL構造類有兩種用法:匿名類和流式構造。構造完成之后,調用toString()方法即可生成對應的SQL語句。
MyBatis文檔 動態SQL
新聞熱點
疑難解答