-
mybatis的強大特性之一就是動態SQL。我們在寫復雜查詢的時候,會發現復雜查詢包括了各種各樣的判斷,我們很難一鼓作氣的寫出完美的查詢。動態SQL語句可以幫助我們拼接不同的SQL語句,而已讓我們的代碼變得更加優雅且功能更加強大。這一篇給大家介紹一下if的用法
下邊就是現在MyBatis的動態SQL在XML中支持的幾種標簽,他們分別是:
- if
- choose
- trim(where、set)
- foreach
-
bind
if用法
if標簽通常用於WHERE語句中,通過判斷參數值來決定是否使用某個查詢條件, 他也經常用於UPDATE語句中判斷是否更新某一個字段,還可以在INSERT語句中用來判斷是否插入某個字段的值
where:(我們的項目中模糊查詢很多都用到了if,如果模糊條件不為空,則執行模糊查詢,如果為空就到此為止)
<select id="FuzzyQueryClassByStrlike" parameterType="java.lang.String" resultType="com.dmsdbj.itoo.basicInfo.entity.ext.DivideClassModel"> select tc.id as classId, tc.class_code as classCode, tc.class_name as className, tc.profession_id as professionId, p.major_name as professionName, p.institution_id as InsititutionId, i.institution_name as InsititutionName from t_class tc inner join t_profession p on tc.profession_id = p.id inner join t_institution i on p.institution_id=i.id <if test="strLike !='' and strLike !=null"> WHERE( tc.class_code LIKE concat('%',#{strLike},'%') OR tc.class_name LIKE concat('%',#{strLike},'%') OR p.major_name LIKE concat('%',#{strLike},'%') OR i.institution_name LIKE concat('%',#{strLike},'%') ) </if>
update(insert同理):如果要更新很多字段,但是一個步驟就可以完成,我們就可以使用if來進行判斷,如果這個參數不為空則更新
<update id="updateById" parameterType="com.dmsdbj.itoo.basicInfo.entity.EducationExperienceEntity"> update t_education_experience <set> <if test="remark != null"> remark = #{remark,jdbcType=VARCHAR}, </if> <if test="operator != null"> operator = #{operator,jdbcType=VARCHAR}, </if> <if test="endDate != null"> end_date = #{endDate,jdbcType=DATE}, </if> <if test="schoolName != null"> school_name = #{schoolName,jdbcType=VARCHAR}, </if> <if test="startDate != null"> start_date = #{startDate,jdbcType=DATE}, </if> <if test="teacherName != null"> teacher_name = #{teacherName,jdbcType=VARCHAR}, </if> <if test="studentId != null"> student_id = #{studentId,jdbcType=VARCHAR}, </if> <if test="isDelete != null"> is_delete = #{isDelete,jdbcType=TINYINT}, </if> <if test="education != null"> education = #{education,jdbcType=VARCHAR}, </if> <if test="createTime != null"> create_time = #{createTime,jdbcType=TIMESTAMP}, </if> <if test="updateTime != null"> update_time = #{updateTime,jdbcType=TIMESTAMP}, </if> </set> where id = #{id,jdbcType=VARCHAR} and is_delete = 0 </update>
注意:
if標簽中有一個test屬性,test屬性值是一個符合OGNL要求的判斷表達式,表達式的結果可以使true或者false,除此之外所有的非0值都為true。
上一篇中我們講解了if標簽的使用,但是他無法實現if…else的邏輯判斷,這就要用到我們這一篇提到的choose when otherwise標簽。
使用規則:
一個choose中至少有一個when,有0個或一個otherwise
舉個例子:
<select id="selectByIdOrUserName" resultType="cd.mybatis.model.SysUser"> select id, user_name userName, user_password UserPassword, user_info userInfo from sys_user where 1=1 <choose> <when test="id!=null"> and id=#{id} </when> <when test="userName !=null and userName !='' "> and user_name =#{uerName} </when> <otherwise> and 1=2 </otherwise> </choose> </select>
代碼解釋:
查詢用戶的信息,如果提供了id,那么優先使用id查詢,如果沒有id,提供了username,那么使用username作為條件查詢,如果都沒有則執行otherwise,確保返回值的正確
上一篇博客我們簡單的介紹了一下choose when otherwise的用法,這一篇我們來聊聊另外當個差不多的標簽的用法:where、set、trim
1. where標簽的作用:如果該標簽包含的元素中有返回值,就插入一個where;如果where后面的字符是以AND和OR開頭的,就講他們剔除
舉個例子:
<select id="selectByUser" resultType="cd.mybatis.simple.model.SysUser"> select id, user_name userName, user_password userPassWord, user_email userEmail, user_info userInfo, user_img headImg, create_time createTime from sys_user where 1=1 <if test="userName != null and userName !=''"> and user_name like concat('%',#{userName},'%') </if> <if test="userEmail !=''and userEmail !=null"> and user_email=#{userEmail} </if> </select>
使用where標簽修改后:
<select id="selectByUser" resultType="tk.mybatis.simple.model.SysUser"> select id, user_name userName, user_password userPassWord, user_email userEmail, user_info userInfo, user_img headImg, create_time createTime from sys_user <where> <if test="userName != null and userName !=''"> and user_name like concat('%',#{userName},'%') </if> <if test="userEmail !=''and userEmail !=null"> and user_email=#{userEmail} </if> </where> </select>
第一個例子中,如果沒有where1=1,當兩個if條件都不滿足時,最后生成的SQL就會以where結束,這樣不符合SQL規范,所以需要加一個默認為true的條件
第二個例子,如果兩個if條件不滿足的時候,where標簽包着的這一段代碼就會被剔除掉,在SQL中就不會出現這一段代碼了。
2.set標簽的作用:如果該標簽包含的元素中有返回值,就插入一個set;如果set后面的字符串是以逗號結尾的,就將這個逗號剔除
舉個例子:
<!--批量更新學生信息-XX-2017-7-24 17:00:08--> <update id="updateStudentList"> <foreach collection="studentEntitys" item="item" index="index" open="" close="" separator=";"> update t_student <set> <if test="item.classesId!='' and item.classesId!=null"> classes_id=${item.classesId} </if> <if test="item.code!='' and item.code!=null"> code=${item.code} </if> <if test="item.roomId!='' and item.roomId!=null"> room_id=${item.roomId} </if> </set> where id = ${item.id} </foreach> </update>
注意最后的where id=${item.id} 是不可省略的,如果set包含的內容為空,只能避免最后遺留的逗號問題
3.trim用法:where和set標簽的功能都可以使用trim標簽來實現,並且在底層就是通過TrimSqlNode實現的
where標簽對應的trim實現:
<trim prefix="WHERE" prefixOverrides="AND |OR "> ... </trim>
set標簽對應的trim實現:
<trim prefix="SET" prefixOverrides=","> ... </trim>
trim屬性
- prefix:當trim元素內包含內容時,會給內容增加prefix指定前綴
- prefixOverrides: 當trim元素內包含內容時,會把內容中匹配的前綴字符串去掉
- suffix: 當trim元素內包含內容時,會給內容增加suffix指定的后綴
- suffixOverrides:當trim內包含內容時,會把內容中匹配的后綴字符串去掉。
mybatis中大於等於小於等於的寫法
第一種寫法(1):
原符號 < <= > >= & ' " 替換符號 < <= > >= & ' " 例如:sql如下: create_date_time >= #{startTime} and create_date_time <= #{endTime} 第二種寫法(2): 大於等於 <![CDATA[ >= ]]> 小於等於 <![CDATA[ <= ]]> 例如:sql如下: create_date_time <![CDATA[ >= ]]> #{startTime} and create_date_time <![CDATA[ <= ]]> #{endTime}