在實際開發中,數據庫的查詢很難一蹴而就,咱們每每要根據各類不一樣的場景拼接出不一樣的SQL語句,這無疑是一項複雜的工做,咱們在使用mybatis時,mybatis給咱們提供了動態SQL,可讓咱們根據具體的業務邏輯來拼接不一樣的SQL語句。OK,那麼咱們今天就來看看如何使用mybatis中的動態SQL。
mybatis中的動態SQL主要包含以下幾種元素:if、choose、when、otherwise、trim、where、set以及foreach幾種,咱們下面分別來看看這幾種。git
if是mybatis動態SQL中的判斷元素,這個有點相似於Java中的if語句,不一樣的是這裏的if通常經常和test配合使用。咱們來看一個簡單的例子:github
<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這個接口中定義的相關方法:sql
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();
}
}
查詢結果:
若是我將查詢條件設爲空字符串,以下:markdown
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語句的差別。mybatis
choose有點相似於Java中的switch,經常配合when和otherwise一塊兒來使用。咱們來看一個簡單的例子:app
<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的全部數據。ide
在上面的案例中小夥伴們可能都發現了一個問題,就是咱們在添加查詢條件的時候,在查詢條件以前都先添加了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中,這樣就比前一種方式簡單許多。ui
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
,我在查詢的時候可能只是傳入了一個list集合,該集合中有西安和北京兩個查詢條件,那我如何將這個集合組裝成一個sql語句呢?很簡單,以下:
WHERE address IN('西安','北京')
<select id="getUserInCities" resultMap="u">
SELECT * FROM user2
WHERE address IN
<foreach collection="cities" index="city" open="(" separator="," close=")" item="city">
#{city}
</foreach>
</select>
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 技術原理與實戰》第五章