MyBatis采用功能强大的基于OGNL的表达式来消除其他元素
if
choose(when,otherwise)
trim(where,set)
foreach
if
动态sql通常要做的事情是有条件的包含where子句的一部分。比如:
<select id="findActiveBlogWithTitleLike" resultBype="Blog">
select * from blog where state=`active`
<if test="title != null" >
and title like #{title}
</if>
</select>
就这个例子而言,我们发现其实参数值是可以包含通配符的。
如果想要可选的通过“title”和“author”两个条件搜索该怎么办呢?
首先,改变语句的名称让它更具有实际意义;然后只要加入一个条件即可。
<select id="findActiveBlogLike" resutlType="Blog">
select * from blog where state=`active`
<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>
choose,when,otherwise
有些时候,我们不想用到所以的条件语句,而只想其中择其一二。针对这种情况,MyBatis提供了choose元素,它有点像java中的switch语句。
<select id="findActiveBlogLike" resultType="Blog">
select * from blog where state = `active`
<choose>
<when test="title != null">
and title like #{title}
</when>
<when text="author != null and author.name != null">
and author_name like #{author.name}
</when>
<otherwise>
and featured =1
</otherwise>
</choose>
</select>
trim ,where ,set
前面几个例子已经完美的解决了动态sql的问题。现在考虑回到“if”实例,这次我们我们将“active = 1”也设置成为动态的条件,看看会发生什么。
<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 title like #{title}
</if>
<if test="author != null and author.name != null">
and author_name like #{author.name}
</select>
这个查询看似合理,但是它对数据环境的要求太苛刻,非常容易导致失败。
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>