在實際開發中,數據庫的查詢很難一蹴而就,我們往往要根據各種不同的場景拼接出不同的SQL語句,這無疑是一項復雜的工作,我們在使用mybatis時,mybatis給我們提供了動態SQL,可以讓我們根據具體的業務邏輯來拼接不同的SQL語句。OK,那么我們今天就來看看如何使用mybatis中的動態SQL。 mybatis中的動態SQL主要包含如下幾種元素:if、choose、when、otherwise、trim、where、set以及foreach幾種,我們下面分別來看看這幾種。
if是mybatis動態SQL中的判斷元素,這個有點類似于java中的if語句,不同的是這里的if一般常常和test配合使用。我們來看一個簡單的例子:
<select id="getUser" resultMap="u" parameterType="String"> select * from user2 <if test="address!=null and address !=''"> WHERE address LIKE concat('%',#{address},'%') </if> </select>當用戶傳入的address不為null或者空字符串的時候,我就加上一個where條件,否則就什么條件都不加入。然后我們再來看看我們在UserMapper這個接口中定義的相關方法:
public List<User> getUser(@Param("address") String address);我們在調用這個方法的時候,如果傳入了address參數,那么查詢條件中就有address,否則就沒有。來看看測試代碼:
Sqlsession sqlSession = null; try { sqlSession = DBUtils.openSqlSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); List<User> list = mapper.getUser("西安"); for (User user : list) { System.out.PRintln(user); } sqlSession.commit(); } catch (Exception e) { System.err.println(e.getMessage()); sqlSession.rollback(); } finally { if (sqlSession != null) { sqlSession.close(); } }查詢結果:
如果我將查詢條件設為空字符串,如下:

小伙伴們注意兩個查詢結果截圖中打印出來的SQL語句的差異。
choose有點類似于Java中的switch,常常配合when和otherwise一起來使用。我們來看一個簡單的例子:
<select id="getUser2" resultMap="u"> SELECT * FROM user2 WHERE 1=1 <choose> <when test="id!=null"> AND id=#{id} </when> <when test="address!=null"> AND address=#{address} </when> <when test="username!=null"> AND user_name LIKE concat(#{username},'%') </when> <otherwise> AND 10>id </otherwise> </choose> </select>在查詢條件中,如果用戶傳來了id,那么我就查詢該id的數據,如果用戶傳來了address,那么我就我們添加address的查詢條件,如果用戶傳來了username,那么我就添加username的查詢條件,最后如果用戶任何一個查詢條件都沒有添加進來,那么默認查詢條件就是查詢id小于10的所有數據。
在上面的案例中小伙伴們可能都發現了一個問題,就是我們在添加查詢條件的時候,在查詢條件之前都先添加了where 1=1,然后后面直接在這之后再追加and什么什么的,那么每次這樣來寫顯然有點麻煩,有沒有簡單一點的方案呢?當然有,我們可以通過where元素,如下:
<select id="getUser3" resultMap="u"> SELECT * FROM user2 <where> <choose> <when test="id!=null"> AND id=#{id} </when> <when test="address!=null"> AND address=#{address} </when> <when test="username!=null"> AND user_name LIKE concat(#{username},'%') </when> <otherwise> AND 10>id </otherwise> </choose> </where> </select>這樣,只有where元素中有條件成立,才會將where關鍵字組裝到SQL中,這樣就比前一種方式簡單許多。
trim有點元素替換的意思,還是上面的案例,我們可以將and替換為where,如下:
<select id="getUser4" resultMap="u"> SELECT * FROM user2 <trim prefix="where" prefixOverrides="and"> AND id=1 </trim> </select>這個最終執行的sql是SELECT * FROM user2 where id=1。
set是我們在更新表的時候使用的元素,通過set元素,我們可以逐字段的修改一條數據,如下:
<update id="update"> UPDATE user2 <set> <if test="username!=null"> user_name=#{username}, </if> <if test="passWord!=null"> password=#{password} </if> </set> WHERE id=#{id} </update>在set元素中,如果遇到了逗號,系統會自動將之去除。
foreach元素用來遍歷集合,比如我想查詢多個城市的人,我的sql語句可能是這樣SELECT * FROM user2 WHERE address IN('西安','北京'),我在查詢的時候可能只是傳入了一個list集合,該集合中有西安和北京兩個查詢條件,那我如何將這個集合組裝成一個sql語句呢?很簡單,如下:
collection表示傳入的參數中集合的名稱,index表示是當前元素在集合中的下標,open和close則表示如何將集合中的數據包裝起來,separator表示分隔符,item則表示循環時的當前元素。這樣一段配置最終組合成的sql就是SELECT * FROM user2 WHERE address IN('西安','北京')。
使用bind元素我們可以預先定義一些變量,然后在查詢語句中使用,如下:
<select id="getUserByName" resultMap="u"> <bind name="un" value="username+'%'"></bind> SELECT* FROM user2 WHERE user_name LIKE #{un} </select>這個貌似沒什么難度,不再贅述。
以上。
本文案例下載: 本文案例GitHub地址https://github.com/lenve/JavaEETest/tree/master/Test27-mybatis9
以上。
參考資料: 《深入淺出MyBatis 技術原理與實戰》第五章
新聞熱點
疑難解答