初次接触mybatis的时候,是不是遇到过这样的情况呢?
<select id="findActiveBlogLike"
resultType="Blog">
SELECT * FROM BLOG
WHERE
<if test="state != null">
state = #{state}
</if>
<if test="title != null">
AND title like #{title}
</if>
<if test="author != null and author.name != null">
AND author_name like #{author.name}
</if>
</select>
如果这些条件没有一个能匹配上将会怎样?最终这条 SQL 会变成这样:
SELECT * FROM BLOG
WHERE
这会导致查询失败。
如果仅仅第二个条件匹配又会怎样?这条 SQL 最终会是这样:
SELECT * FROM BLOG
WHERE
AND title like ‘someTitle’
也许你会聪明的这么写:
<pre name="code" class="html"><select id="findActiveBlogLike"
resultType="Blog">
SELECT * FROM BLOG
WHERE <span style="color:#ff0000;">1=1</span>
<if test="state != null">
state = #{state}
</if>
<if test="title != null">
AND title like #{title}
</if>
<if test="author != null and author.name != null">
AND author_name like #{author.name}
</if>
</select>
这样写其实并不优美,如果你查看mybatis的官方文档,那么你就会发现mybatis提供了动态sql的支持,解决上面的情况有两种方法:
第一种是通过
<where>标签
MyBatis 有一个简单的处理,这在90%的情况下都会有用。而在不能使用的地方,你可以自定义处理方式来令其正常工作。一处简单的修改就能得到想要的效果:
<select id="findActiveBlogLike" resultType="Blog"> SELECT * FROM BLOG <where> <if test="state != null"> state = #{state} </if> <if test="title != null"> AND title like #{title} </if> <if test="author != null and author.name != null"> AND author_name like #{author.name} </if> </where> </select>where 元素知道只有在一个以上的if条件有值的情况下才去插入“WHERE”子句。而且,若最后的内容是“AND”或“OR”开头的,where 元素也知道如何将他们去除。
如果 where 元素没有按正常套路出牌,我们还是可以通过自定义 trim 元素来定制我们想要的功能。比如,和 where 元素等价的自定义 trim 元素为:
<trim prefix="WHERE" prefixOverrides="AND |OR "> ... </trim>
- <select id="getStudentList_if_trim" resultMap="resultMap_studentEntity">
- SELECT ST.STUDENT_ID,
- ST.STUDENT_NAME,
- ST.STUDENT_SEX,
- ST.STUDENT_BIRTHDAY,
- ST.STUDENT_PHOTO,
- ST.CLASS_ID,
- ST.PLACE_ID
- FROM STUDENT_TBL ST
- <trim prefix="WHERE" prefixOverrides="AND|OR">
- <if test="studentName !=null ">
- ST.STUDENT_NAME LIKE CONCAT(CONCAT('%', #{studentName, jdbcType=VARCHAR}),'%')
- </if>
- <if test="studentSex != null and studentSex != '' ">
- AND ST.STUDENT_SEX = #{studentSex, jdbcType=INTEGER}
- </if>
- <if test="studentBirthday != null ">
- AND ST.STUDENT_BIRTHDAY = #{studentBirthday, jdbcType=DATE}
- </if>
- <if test="classId != null and classId!= '' ">
- AND ST.CLASS_ID = #{classId, jdbcType=VARCHAR}
- </if>
- <if test="classEntity != null and classEntity.classId !=null and classEntity.classId !=' ' ">
- AND ST.CLASS_ID = #{classEntity.classId, jdbcType=VARCHAR}
- </if>
- <if test="placeId != null and placeId != '' ">
- AND ST.PLACE_ID = #{placeId, jdbcType=VARCHAR}
- </if>
- <if test="placeEntity != null and placeEntity.placeId != null and placeEntity.placeId != '' ">
- AND ST.PLACE_ID = #{placeEntity.placeId, jdbcType=VARCHAR}
- </if>
- <if test="studentId != null and studentId != '' ">
- AND ST.STUDENT_ID = #{studentId, jdbcType=VARCHAR}
- </if>
- </trim>
- </select>