Mybatis学习笔记(六)
动态SQL
通常使用动态SQL不可能是独立的一部分,MyBatis当然使用一种强大的动态SQL语言来改进这种情形,这种语言可以被用在任意映射的SQL语句中。
MyBatis采用功能强大的基于OGNL的表达式来消除其他元素。
?if
?choose(when,otherwise)
?trim(where,set)
?foreach
if
在动态SQL中所做的最通用的事情是包含部分where字句的条件。比如:
?
[html]?view plaincopy- <select?id=”findActiveBlogWithTitleLike”??
- ????parameterType=”Blog”?resultType=”Blog”>??
- ????????SELECT?*?FROM?BLOG??
- ????????WHERE?state?=??ACTIVE???
- ????????<if?test=”title?!=?null”>??
- ????????????AND?title?like?#{title}??
- ????????</if>??
- </select>??
choose, when, otherwise
和Java中的switch语句相似,MyBatis提供choose元素。
[html]?view plaincopy
- <select?id=”findActiveBlogLike”??
- ????parameterType=”Blog”?resultType=”Blog”>??
- ????????SELECT?*?FROM?BLOG?WHERE?state?=??ACTIVE???
- ????????<choose>??
- ????????????<when?test=”title?!=?null”>??
- ????????????????AND?title?like?#{title}??
- ????????????</when>??
- ????????????<when?test=”author?!=?null?and?author.name?!=?null”>??
- ????????????????AND?title?like?#{author.name}??
- ????????????</when>??
- ????????????<otherwise>??
- ????????????????AND?featured?=?1??
- ????????????</otherwise>??
- ????????</choose>??
- </select>??
trim, where, set
上面的例子中如果把“state = ?ACTIVE?”也设置为动态的话就有可能出现问题。所以,
[html]?view plaincopy
- <select?id=”findActiveBlogLike”??
- ????????parameterType=”Blog”?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?#{author.name}??
- ????????</if>??
- ????</where>??
- </select>??
如果where元素没有做出你想要的,你可以使用trim元素来自定义。比如,和where元素相等的trim元素是:[html]?view plaincopy
- <trim?prefix="WHERE"?prefixOverrides="AND?|OR?">??
- …??
- </trim>??
和动态更新语句相似的解决方案是set。set元素可以被用于动态包含更新的列,而不包含不需更新的。比如:
[html]?view plaincopy
- <update?id="updateAuthorIfNecessary"??
- ????????parameterType="domain.blog.Author">??
- ????update?Author??
- ????<set>??
- ????????<if?test="username?!=?null">username=#{username},</if>??
- ????????<if?test="password?!=?null">password=#{password},</if>??
- ????????<if?test="email?!=?null">email=#{email},</if>??
- ????????<if?test="bio?!=?null">bio=#{bio}</if>??
- ????</set>??
- ????where?id=#{id}??
- </update>??
如果你对和这相等的trim元素好奇,它看起来就是这样的:
[html]?view plaincopy
- <trim?prefix="SET"?suffixOverrides=",">??
- …??
- </trim>??
foreach
另外一个动态SQL通用的必要操作是迭代一个集合,通常是构建在IN条件中的。比如:
[html]?view plaincopy
- <select?id="selectPostIn"?resultType="domain.blog.Post">??
- ????SELECT?*??
- ????FROM?POST?P??
- ????WHERE?ID?in??
- ????<foreach?item="item"?index="index"?collection="list"??
- ????????????open="("?separator=","?close=")">??
- ????????#{item}??
- ????</foreach>??
- </select>??
注意:你可以传递一个List实例或者数组作为参数对象传给MyBatis。当你这么做的时候,MyBatis会自动将它包装在一个Map中,用名称作为键。List实例将会以“list”作为键,而数组实例将会以“array”作为键。