當(dāng) where 中的條件使用的 if 標(biāo)簽較多時(shí),這樣的組合可能會(huì)導(dǎo)致錯(cuò)誤。當(dāng) java 代碼按如下方法調(diào)用時(shí):
@Test public void select_test_where() { User user = new User(); user.setUsername(null); user.setSex(1); List<User> userList = this.dynamicSqlMapper.getUsertList_where(user); for (User u : userList ) { System.out.println(u.toString()); } }
如果上面例子,參數(shù) username 為 null,將不會(huì)進(jìn)行列 username 的判斷,則會(huì)直接導(dǎo)“WHERE AND”關(guān)鍵字多余的錯(cuò)誤 SQL。
這時(shí)可以使用 where 動(dòng)態(tài)語句來解決。“where”標(biāo)簽會(huì)知道如果它包含的標(biāo)簽中有返回值的話,它就插入一個(gè)‘where’。此外,如果標(biāo)簽返回的內(nèi)容是以 AND 或OR 開頭的,則它會(huì)剔除掉。
上面例子修改為:
<select id="getUserList_whereIf" resultMap="resultMap_User" parameterType="com.yiibai.pojo.User"> SELECT u.user_id, u.username, u.sex, u.birthday FROM User u <where> <if test="username !=null "> u.username LIKE CONCAT(CONCAT('%', #{username, jdbcType=VARCHAR}),'%') </if> <if test="sex != null and sex != '' "> AND u.sex = #{sex, jdbcType=INTEGER} </if> <if test="birthday != null "> AND u.birthday = #{birthday, jdbcType=DATE} </if> </where> </select>
where 主要是用來簡化 sql 語句中 where 條件判斷,自動(dòng)地處理 AND/OR 條件。
<select id="dynamicWhereTest" parameterType="Blog" resultType="Blog"> select * from t_blog <where> <if test="title != null"> title = #{title} </if> <if test="content != null"> and content = #{content} </if> <if test="owner != null"> and owner = #{owner} </if> </where> </select>
where 元素的作用是會(huì)在寫入 where 元素的地方輸出一個(gè) where,另外一個(gè)好處是你不需要考慮 where 元素里面的條件輸出是什么樣子的,MyBatis 會(huì)智能的幫處理,如果所有的條件都不滿足那么 MyBatis 就會(huì)查出所有的記錄,如果輸出后是 and 開頭的,MyBatis 會(huì)把第一個(gè)and忽略,當(dāng)然如果是 or 開頭的,MyBatis 也會(huì)把它忽略;此外,在 where 元素中你不需要考慮空格的問題,MyBatis 會(huì)智能的幫你加上。像上述例子中,如果 title=null, 而 content != null,那么輸出的整個(gè)語句會(huì)是 select * from t_blog where content = #{content},而不是 select * from t_blog where and content = #{content},因?yàn)?MyBatis 會(huì)自動(dòng)地把首個(gè) and / or 給忽略。