51Testing软件测试论坛

 找回密码
 (注-册)加入51Testing

QQ登录

只需一步,快速开始

微信登录,快人一步

手机号码,快捷登录

查看: 1521|回复: 0
打印 上一主题 下一主题

MyBatis进阶使用——动态SQL

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2019-2-2 10:23:19 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
MyBatis的强大特性之一就是它的动态SQL。如果你有使用JDBC或者其他类似框架的经验,你一定会体会到根据不同条件拼接SQL语句的痛苦。然而利用动态SQL这一特性可以彻底摆脱这一痛苦
MyBatis精简了元素种类,在MyBatis3中,我们只需要学习以下4种元素:
  • if
  • choose(when,otherwise)
  • trim(where,set)
  • foreach
if
动态SQL通常要做的事情就是根据条件包含where子句的一部分,比如:
<select id="findActiveBlogWithTitleLike"     resultType="Blog">  SELECT * FROM BLOG   WHERE state = ‘ACTIVE’   <if test="title != null">    AND title like #{title}  </if></select>
这条语句提供了一种可选的查找文本功能。如果没有传入“title”,那么就返回所有处于“ACTIVE”状态的博文。反之则还要进行根据“title”参数的模糊查找。
在一个标签中,可以如上面例子一般,嵌套多个if元素。
choose, when, otherwise
如果我们不想应用所有的条件语句而是像switch语句一般进行选择的话,那么我们就应该使用choose元素。
修改上面那个例子,如果存在“title”参数则按照“title”查找,如果提供了“author”参数就按照“author”查找。如果两者都没有提供就返回所有符合条件的博文。
<select id="findActiveBlogLike"     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 author_name like #{author.name}    </when>    <otherwise>      AND featured = 1    </otherwise>  </choose></select>trim , where , set
那么我们现在希望将所有的where子句的条件都变成动态SQL,可能会编写出这样的代码:
<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 BLOGWHERE
如果只有第二个匹配上的话,会变成这样:
SELECT * FROM BLOGWHERE AND title like ‘someTitle’
这些查询都会失败,为了解决这个问题,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>  </where></select>
where元素只有在至少一个子元素的条件返回SQL子句的情况下才插入“WHERE”子句。而且若语句的开头为AND或者OR也会将它们去除。
如果希望定制where的行为,我们可以通过自定义trim元素来定制where元素的功能。比如和where元素等价的自定义trim元素为:
<trim prefix="WHERE" prefixOverrides="AND |OR ">  ... </trim>
类似的用于动态更新语句的解决方案叫做set。set元素可以用于动态包含所需要更新的列,而舍弃其他。比如:
<update id="updateAuthorIfNecessary">  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>
这里set元素会动态前置SET关键字同时删除无关的逗号。
foreach
动态SQL的另外一个常用的操作需求就是对一个集合进行遍历通常是在构建IN条件语句的时候,比如:
<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>
foreach元素的功能非常强大,它袁旭你指定一个集合,声明可以在元素体内使用的集合项和索引变量。也允许你指定开头和结尾的字符串以及在迭代结果之间放置分隔符。
注意: 我们可以使用任何可迭代对象传递给foreach作为集合参数。当使用可迭代对象或者数组时,index是当前迭代的次数,itme是本次迭代获取的元素。当使用Map对象时,index是键,item是值。

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏
回复

使用道具 举报

本版积分规则

关闭

站长推荐上一条 /1 下一条

小黑屋|手机版|Archiver|51Testing软件测试网 ( 沪ICP备05003035号 关于我们

GMT+8, 2024-11-26 13:31 , Processed in 0.064747 second(s), 24 queries .

Powered by Discuz! X3.2

© 2001-2024 Comsenz Inc.

快速回复 返回顶部 返回列表