1.mybatis动态sql

mybatis 的强大特性之一便是它的动态 sql,即拼接sql字符串。如果你有使用 jdbc 或其他类似框架的经验,你就能体会到根据不同条件拼接 sql 语句有多么痛苦。拼接的时候要确保不能忘了必要的空格,还要注意省掉列名列表最后的逗号。利用动态 sql 这一特性可以彻底摆脱这种痛苦。

通常使用动态 sql 不可能是独立的一部分,mybatis 当然使用一种强大的动态 sql 语言来改进这种情形,这种语言可以被用在任意的 sql 映射语句中。

动态 sql 元素和使用 jstl 或其他类似基于 xml 的文本处理器相似。在 mybatis 之前的版本中,有很多的元素需要来了解。mybatis 3 大大提升了它们,现在用不到原先一半的元素就可以了。mybatis 采用功能强大的基于 ognl 的表达式来消除其他元素。

2.动态sql标签:if,choose (when, otherwise),trim (where, set),foreach

2.1 if标签:直接上代码

<select id="querybyidandtitle"
     resulttype="blog">
  select * from blog 
  where 1=1 
  <if test="id!= null and title!=null">
    and id=#{id} and title=#{title}
  </if>
</select>

注:if标签一般用于非空验证,如上例,若id为空,if标签里的代码,将不会执行,反之,则会执行。

2.2 choose(when,otherwise)标签:直接上代码

<select id="queryby"
     resulttype="blog">
  select * from blog where 1=1
  <choose>
    <when test="title != null">
      and title like #{title}
    </when>
    <otherwise>
      and id= 1
    </otherwise>
  </choose>
</select>

注:choose(when,otherwise)标签相当于switch(case,default) ,如上例,若title 为空,when标签里的代码,将不会执行,默认执行otherwise标签里面的代码。

2.3 trim(where,set)标签:直接上代码

<select id="queryby" resulttype="com.scme.pojo.user" parametertype="com.scme.pojo.user">
                 select * from user 
                 <where>
                         <if test="username!=null and password!=null">
                             and username=#{username} and password=#{password}
                         </if>
                 </where>
</select>

注:假设上例传入的username,password不为空,代码就可以运行成功!但朋友们可能有疑问了,实际上执行的sql语句是什么呢?其实,sql为:select * from user

 where username=? and password=?  朋友们是否发现,where标签代替了sql中where关键字,但if中的and不见了。其实where标签可以自动去除是“and”或“or”开头的sql中的“and”或“or”关键字。

如果 where 元素没有按正常套路出牌,我们还是可以通过自定义 trim 元素来定制sql,实现where标签的效果。代码如下:

<select id="queryby" resulttype="com.scme.pojo.user" parametertype="com.scme.pojo.user">
                 select * from user 
                 <trim prefix="where" prefixoverrides="and |or ">
                          <if test="username!=null and password!=null">
                             and username=#{username} and password=#{password}
                         </if>
                </trim>
                 <!-- 效果同上
          <where>
                         <if test="username!=null and password!=null">
                             and username=#{username} and password=#{password}
                         </if>
                 </where> -->
         </select>

set标签,代码如下:

<update id="updateuser" parametertype="com.scme.pojo.user">
                 update user 
                 <set>
                     <if test="username!=null">
                             username=#{username}
                     </if>
                 </set>
                 <where> 
                     <if test="id!=null">
                             id=#{id}
                     </if>
                 </where>
         </update>

注:set标签功能和where标签差不多,set标签代替了sql中set关键字,set标签可以自动去除sql中的多余的“,”

同理,trim标签也可以实现set标签的功能

<update id="updateuser" parametertype="com.scme.pojo.user">
                 update user 
         <trim prefix="set" prefixoverrides=",">
              <if test="username!=null"> username=#{username} </if> 
        </trim>
  
         <where> 
    
            <if test="id!=null"> id=#{id} </if> 
          
        </where>
 </update>

2.4 foreach标签:foreach标签实现批量删除,直接上代码

<delete id="batchdelete" parametertype="java.lang.string">
  delete from user
  where id in
  <foreach item="id" index="index" collection="list"
      open="(" separator="," close=")">
        #{id}
  </foreach>
</delete >

注:foreach标签可迭代任何对象(如列表、集合等)和任何的字典或者数组对象传递给foreach作为集合参数,当使用可迭代对象或者数组时,index是当前迭代的次数,item的值是本次迭代获取的元素。当使用字典(或者map.entry对象的集合)时,index是键,item是值。collection标签可以填(’list’,’array’,’map’)。

foreach元素的属性主要有 item,index,collection,open,separator,close。

item表示集合中每一个元素进行迭代时的别名;

index指 定一个名字,用于表示在迭代过程中,每次迭代到的位置;

open表示该语句以什么开始,

separator表示在每次进行迭代之间以什么符号作为分隔符;

close表示以什么结束。

3.bind

bind 元素可以从 ognl 表达式中创建一个变量并将其绑定到上下文。比如:

<select id="selectblogslike" resulttype="blog">
  <bind name="pattern" value="'%' + _parameter.gettitle() + '%'" />
  select * from blog
  where title like #{pattern}
</select>

4.multi-db vendor support

一个配置了“_databaseid”变量的 databaseidprovider 对于动态代码来说是可用的,这样就可以根据不同的数据库厂商构建特定的语句。比如下面的例子:

<insert id="insert">
  <selectkey keyproperty="id" resulttype="int" order="before">
    <if test="_databaseid == 'oracle'">
      select seq_users.nextval from dual
    </if>
    <if test="_databaseid == 'db2'">
      select nextval for seq_users from sysibm.sysdummy1"
    </if>
  </selectkey>
  insert into users values (#{id}, #{name})
</insert>

动态 sql 中可插拔的脚本语言

mybatis 从 3.2 开始支持可插拔的脚本语言,因此你可以在插入一种语言的驱动(language driver)之后来写基于这种语言的动态 sql 查询。

可以通过实现下面接口的方式来插入一种语言:

public interface languagedriver {
  parameterhandler createparameterhandler(mappedstatement mappedstatement, object parameterobject, boundsql boundsql);
  sqlsource createsqlsource(configuration configuration, xnode script, class<?> parametertype);
  sqlsource createsqlsource(configuration configuration, string script, class<?> parametertype);
}

一旦有了自定义的语言驱动,你就可以在 mybatis-config.xml 文件中将它设置为默认语言:

<typealiases>
  <typealias type="org.sample.mylanguagedriver" alias="mylanguage"/>
</typealiases>
<settings>
  <setting name="defaultscriptinglanguage" value="mylanguage"/>
</settings>

除了设置默认语言,你也可以针对特殊的语句指定特定语言,这可以通过如下的 lang 属性来完成:

<select id="selectblog" lang="mylanguage">
  select * from blog
</select>

或者在你正在使用的映射中加上注解 @lang 来完成:

public interface mapper {
  @lang(mylanguagedriver.class)
  @select("select * from blog")
  list<blog> selectblog();

注意 可以将 apache velocity 作为动态语言来使用,更多细节请参考 mybatis-velocity 项目。

到此这篇关于mybatis动态sql标签的用法详解的文章就介绍到这了,更多相关mybatis动态sql标签内容请搜索www.887551.com以前的文章或继续浏览下面的相关文章希望大家以后多多支持www.887551.com!