MyBatis-动态SQL

前提是你 提交于 2019-12-11 17:56:39


动态SQL也是MyBatis的强大特性之一,在使用JDBC时我们拼接sql语句需要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。而使用MyBatis的动态sql后,这些我们都可以很轻松的解决。

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,来增加查询条件

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 test="author != null and author.name != null">
		and author_name like #{suthor.name}
	</when>
	<otherwise>
		and featured = 1
	</otherwise>
</choose>
</select>

trim(where,set)

使用if,choose元素基本上已经可以解决动态sql的问题了,但是如果我们想连where也动态生成,在没有接收到条件参数时全查询,接收到条件参数在进行where条件查询。如果我们还使用if,choose的话,可能会出现其中一个条件满足,另一个条件符合的情况:where and author_name like ?的问题;这个时候我们可以这样做:

<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元素会将他们去除
如果 where 元素没有按照正常套路出牌,我们还有另一中方法,自定义trim元素来定制where元素的功能:

<trim prefix="where" prefixOverrides="and|or">
----
</trim>

trim中的属性有prefix-前缀值
suffix-后缀值
prefixOverrides-过滤内容的前缀
suffixOverrides-过滤内容的后缀
举例

<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关键字,同时也会删除无关的逗号,因为用了条件语句之后很可能就会在生成sql语句的后面留下这些逗号。
我们可以使用trim定义一个set

<trim prefix="SET" suffixOverrides=",">
  ...
</trim>

此时我们添加了一个前缀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元素的功能非常强大,它允许你指定一个集合,生命可以在元素体内使用的集合项(item)和索引(index)变量。它也允许你指定开头和结尾的字符串以及在迭代结果之间放置分隔符。这个元素很智能,因此他不会偶然的附加多余分隔符。
注意:我们可以将任何可迭代对象(list、set等)、map对象或者数组对象传递给foreach作为集合参数。当使用可迭代对象或者数组时,index时当前迭代次数,item的值是本次迭代获取的元素。当使用map对象时,index是键,item是值

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!