mybatis 动态sql


IF 、WHERE标签:


<select id="findActiveBlogWithTitleLike"

     resultType="Blog">

  SELECT * FROM BLOG

  WHERE state = ‘ACTIVE’

  <if test="title != null">

    AND title like #{title}

  </if>

</select>


WHEN标签:

<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>



对于下面这个例子,如果state为空,无法生成合法的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>


MyBatis自然也有相应的解决办法。就是使用where标签改写。where标签非常智能。如果标签内部没有合适的语句,where标签就不会生成任何东西,防止出现错误语句。


<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标签还不能满足需求。这时候还可以使用trim标签进行更高级的定制。trim标签中的prefix和suffix属性会被用于生成实际的SQL语句,会和标签内部的语句拼接。如果语句的前面或后面遇到prefixOverrides或suffixOverrides属性中指定的值,MyBatis会自动将它们删除。在指定多个值的时候,别忘了每个值后面都要有一个空格,保证不会和后面的SQL连接在一起。下面这个例子和where标签完全等效。


<trim prefix="WHERE" prefixOverrides="AND |OR ">

  ...

</trim>


还有一个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>


与它等价的trim标签如下。


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

  ...

</trim>




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>




bind标签


bind标签可以将非OGNL表达式值绑定到其中。下面的例子将结果映射中的值绑定到了OGNL表达式中,从而可以直接使用#{}语法访问。


<select id="selectBlogsLike" resultType="Blog">

  <bind name="pattern" value="'%' + _parameter.getTitle() + '%'" />

  SELECT * FROM BLOG

  WHERE title LIKE #{pattern}

</select>



SQL构造类


有时候需要在Java代码中生成SQL语句。如果我们直接编写的话会是一件非常麻烦的事情。由于Java不支持跨行字符串,所以我们要么在一行里面写一个非常非常长的SQL语句,要么用加号拼接出一个笨拙的字符串。MyBatis提供了SQL构造类,我们可以方便的使用这个类构造出SQL语句。


下面这几个例子同样来自于MyBatis文档。SQL构造类有两种用法:匿名类和流式构造。构造完成之后,调用toString()方法即可生成对应的SQL语句。


// 匿名内部类

public String deletePersonSql() {

  return new SQL() {{

    DELETE_FROM("PERSON");

    WHERE("ID = #{id}");

  }}.toString();

}

 

// 流式构造

public String insertPersonSql() {

  String sql = new SQL()

    .INSERT_INTO("PERSON")

    .VALUES("ID, FIRST_NAME", "#{id}, #{firstName}")

    .VALUES("LAST_NAME", "#{lastName}")

    .toString();

  return sql;

}

 

// 如果需要条件构造,只能使用匿名类方式,注意匿名类要引用方法参数的话,参数必须声明为final的

public String selectPersonLike(final String id, final String firstName, final String lastName) {

  return new SQL() {{

    SELECT("P.ID, P.USERNAME, P.PASSWORD, P.FIRST_NAME, P.LAST_NAME");

    FROM("PERSON P");

    if (id != null) {

      WHERE("P.ID like #{id}");

    }

    if (firstName != null) {

      WHERE("P.FIRST_NAME like #{firstName}");

    }

    if (lastName != null) {

      WHERE("P.LAST_NAME like #{lastName}");

    }

    ORDER_BY("P.LAST_NAME");

  }}.toString();

}

 

public String deletePersonSql() {

  return new SQL() {{

    DELETE_FROM("PERSON");

    WHERE("ID = #{id}");

  }}.toString();

}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值