1、動態SQL:if 語句
我們可以發現,如果 #{name} 為空,那么查詢結果也是空,如何解決這個問題呢?使用 if 來判斷
1 <select id="selectByWhere1" resultType="com.zhiyou100.wc.bean.Users"> 2 select 3 <include refid="usercolumns"></include> 4 from users 5 <if test="name!=null "> 6 where name=#{name} 7 </if> 8 <if test="sex!=null and sex!=''"> 9 and sex=#{sex} 10 </if> 11 </select>
這樣寫我們可以看到,如果 sex 等於 null,那么查詢語句為 select * from users where name=#{name},但是如果name 為空呢?那么查詢語句為 select * from users where and sex=#{sex},這是錯誤的 SQL 語句,如何解決呢?請看下面的 where 語句
2、動態SQL:if+where 語句
1 <!--解決:如果第二個條件滿足,第一個條件不滿足。那么就是導致sql語句出錯。 2 if+where:如果第一個條件中 where 並且去掉and 3 --> 4 <select id="selectByWhere2" resultType="com.zhiyou100.wc.bean.Users"> 5 select 6 <include refid="usercolumns"></include> 7 from users 8 <where> 9 <if test="name!=null "> 10 and name=#{name} 11 </if> 12 <if test="sex!=null and sex!=''"> 13 and sex=#{sex} 14 </if> 15 </where> 16 </select>
這個“where”標簽會知道如果它包含的標簽中有返回值的話,它就插入一個‘where’。此外,如果標簽返回的內容是以AND 或OR 開頭的,則它會剔除掉
3、動態SQL:if+set 語句
同理,上面的對於查詢 SQL 語句包含 where 關鍵字,如果在進行更新操作的時候,含有 set 關鍵詞,我們怎么處理呢?
1 <!-- if+set 2 如果傳來的字段為null,那么保留原來的內容 3 --> 4 <update id="updateUser" parameterType="com.zhiyou100.wc.bean.Users"> 5 update users 6 <set> 7 <if test="name!=null"> 8 name=#{name}, 9 </if> 10 <if test="sex!=null"> 11 sex=#{sex}, 12 </if> 13 <if test="age!=0"> 14 age=#{age}, 15 </if> 16 </set> 17 where id=#{id} 18 </update>
4、動態SQL:choose(when,otherwise) 語句
有時候,我們不想用到所有的查詢條件,只想選擇其中的一個,查詢條件有一個滿足即可,使用 choose 標簽可以解決此類問題,類似於 Java 的 switch 語句
1 <!-- choose+when+otherwise --> 2 <select id="selectByWhere3" resultType="com.zhiyou100.wc.bean.Users"> 3 select 4 <include refid="usercolumns"/> 5 from users 6 <where> 7 <choose> 8 <when test="name!=null "> 9 name like concat('%',#{name},'%') 10 </when> 11 <when test="sex!=null and sex!=''"> 12 sex=#{sex} 13 </when> 14 <otherwise> 15 age>=#{age} 16 </otherwise> 17 </choose> 18 </where> 19 </select>
也就是說,這里我們有三個條件,id,name,sex,只能選擇一個作為查詢條件
如果 id 不為空,那么查詢語句為:select * from users where id=?
如果 id 為空,那么看name 是否為空,如果不為空,那么語句為 select * from users where name=?;
如果 name 為空,那么查詢語句為 select * from users where sex=?
5、動態SQL:trim 語句
trim標記是一個格式化的標記,可以完成set或者是where標記的功能
①、用 trim 改寫上面第二點的 if+where 語句
1 <!-- trim --> 2 <select id="selectByWhere4" resultType="com.zhiyou100.wc.bean.Users"> 3 select 4 <include refid="usercolumns"/> 5 from users 6 <!-- 7 prefix:把trim中返回的字符串前添加一個set 8 prefixOverrides:覆蓋trim 中返回的字符串的前綴為and | or 9 suffix:把trim中返回的字符串后添加一個set 10 suffixOverrides:覆蓋trim 中返回的字符串的后綴 11 --> 12 <trim prefix="where" prefixOverrides="and / or"> 13 <if test="name!=null "> 14 name=#{name} 15 </if> 16 <if test="sex!=null and sex!=''"> 17 and sex=#{sex} 18 </if> 19 </trim> 20 </select>
②、用 trim 改寫上面第三點的 if+set 語句
1 <!-- trim --> 2 <update id="updateUser2" parameterType="com.zhiyou100.wc.bean.Users"> 3 update users 4 <!-- 5 prefix:把trim中返回的字符串前添加一個set 6 prefixOverrides:覆蓋trim 中返回的字符串的前綴為and | or 7 suffix:把trim中返回的字符串后添加一個set 8 suffixOverrides:覆蓋trim 中返回的字符串的后綴 9 --> 10 <trim prefix="set" suffixOverrides=","> 11 <if test="name!=null"> 12 name=#{name}, 13 </if> 14 <if test="sex!=null"> 15 sex=#{sex}, 16 </if> 17 <if test="age!=0"> 18 age=#{age}, 19 </if> 20 </trim> 21 where id=#{id} 22 </update>
6、動態SQL: SQL 片段
有時候可能某個 sql 語句我們用的特別多,為了增加代碼的重用性,簡化代碼,我們需要將這些代碼抽取出來,然后使用時直接調用
1 <sql id="usercolumns"> 2 id,name,age,sex 3 </sql>
引用 sql 片段
1 <select id="selectByWhere1" resultType="com.zhiyou100.wc.bean.Users"> 2 select 3 <include refid="usercolumns"></include> 4 from users 5 <if test="name!=null "> 6 where name=#{name} 7 </if> 8 <if test="sex!=null and sex!=''"> 9 and sex=#{sex} 10 </if> 11 </select>
注意:①、最好基於 單表來定義 sql 片段,提高片段的可重用性
②、在 sql 片段中不要包括 where
7、動態SQL: foreach 語句
需求:我們需要查詢 user 表中 id 分別為1,2,3的用戶
sql語句:delete from users where id=1 or id=2 or id=3
delete from users where id in (1,2,3)
1、我們用 foreach 來改寫 delete from users where id in (1,2,3)
1 <!-- delete通過foreach --> 2 <delete id="deleteByIds"> 3 delete from users where id in 4 <!-- 5 collection:指定輸入對象中的集合屬性 6 item:每次遍歷生成的對象 7 open:開始遍歷時的拼接字符串 8 close:結束時拼接的字符串 9 separator:遍歷對象之間需要拼接的字符串 10 --> 11 <foreach collection="ids" open="(" close=")" separator="," item="id"> 12 #{id} 13 </foreach> 14 15 </delete>
2、我們用 foreach 來改寫 delete from users where id=1 or id=2 or id=3
1 <delete id="deleteByIds2"> 2 delete from users 3 <!-- 4 collection:指定輸入對象中的集合屬性 5 item:每次遍歷生成的對象 6 open:開始遍歷時的拼接字符串 7 close:結束時拼接的字符串 8 separator:遍歷對象之間需要拼接的字符串 9 delete from users where id=1 or id=2 or id=3 10 --> 11 <foreach collection="ids2" open="where" separator="or" item="id"> 12 id=#{id} 13 </foreach> 14 15 </delete>
測試:
1 /** 2 * delete in() 3 */ 4 @Test 5 void testdeleteByIds() { 6 List<Integer> ids=new ArrayList<>(); 7 ids.add(7); 8 ids.add(8); 9 usersDao.deleteByIds(ids); 10 } 11 /** 12 * delete or 13 */ 14 @Test 15 void testdeleteByIds2() { 16 List<Integer> ids2=new ArrayList<>(); 17 ids2.add(6); 18 ids2.add(9); 19 usersDao.deleteByIds2(ids2); 20 }
3.模糊查詢
1.UsersMapper.xml
1 <!-- choose+when+otherwise 模糊查詢 --> 2 <select id="selectByWhere3" resultType="com.zhiyou100.wc.bean.Users"> 3 select 4 <include refid="usercolumns"/> 5 from users 6 <where> 7 <choose> 8 <when test="name!=null "> 9 name like concat('%',#{name},'%') 10 </when> 11 <when test="sex!=null and sex!=''"> 12 sex=#{sex} 13 </when> 14 <otherwise> 15 age>=#{age} 16 </otherwise> 17 </choose> 18 </where> 19 </select>
2.Usersdao
1 public List<Users> selectByWhere3(Users users);
3.測試
1 /** 2 * 模糊查詢 3 */ 4 @Test 5 void testSelectByWhere3() { 6 Users users= new Users(); 7 users.setName("晨"); 8 users.setSex("男"); 9 List<Users> list=usersDao.selectByWhere3(users); 10 System.out.println(list); 11 }