MyBatis动态SQL

MyBatis动态SQL

动态SQL简介

动态 SQL 是 MyBatis 的强大特性之一。如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL,可以彻底摆脱这种痛苦。

使用动态 SQL 并非一件易事,但借助可用于任何 SQL 映射语句中的强大的动态 SQL 语言,MyBatis 显著地提升了这一特性的易用性。

如果你之前用过 JSTL 或任何基于类 XML 语言的文本处理器,你对动态 SQL 元素可能会感觉似曾相识。在 MyBatis 之前的版本中,需要花时间了解大量的元素。借助功能强大的基于 OGNL 的表达式,MyBatis 3 替换了之前的大部分元素,大大精简了元素种类,现在要学习的元素种类比原来的一半还要少。

常用的动态SQL标签

  • if
  • choose (when, otherwise)
  • trim (where, set)
  • foreach

为什么要用动态SQL

动态SQL可以根据传入的查询条件,灵活的拼接SQL语句

动态SQL用法

if标签

if标签语法

<select...>
  SQL语句1
  <if test="条件表达式">
     SQL语句2
  </if>
</select>

条件表达式大于、小于、大于等于、小于等于判断
image

if条件判断各种使用方式

  1. 如果参数为数字类型的时候没有特俗需求的情况只需要判断是否为null即可

例如:

<if test="id != null"> </if>

如果有特俗需求,例如判断是否大于某个数的时候才行。只需要加上对应的条件判断即可

例如:

<if test='id != null and id > 28'></if>

mybatis对于这种大于小于等等还有另一种形式

例如:

<if test='id != null and id gt 28'></if>

对应关系:

image

  1. 如果参数字符串类型
  • 如果不需要过滤空串的情况 仅仅判断null即可
<if test="username != null"></if>
  • 如果需要过滤空串,添加空串判断即可 不支持 && 所以这里用 and or || 来做逻辑与或的判断
<if test="username != null and '' != username"></if> 
或者 
<if test="username != null and ''  neq username"></if>
  • 如果判断字符串是否已某个特俗字符开头,结尾等。直接调用String的对应方法即可
<!-- 是否以什么开头 -->
<if test="username != null and username.indexOf('ji') == 0"> </if>
<!-- 是否包含某字符 -->
<if test="username != null and username.indexOf('ji') >= 0"> </if>
<!-- 是否以什么结尾 -->
<if test="username != null and username.lastIndexOf('ji') > 0"></if> 
  • 是否是某个特定字符串,某些业务有此需要。
<if test="username != null and 'hello' == username"></if> 
或者
<if test="username != null and 'hello' eq username"></if>

注意:

<if test="username != null and 'hello' == username"></if>

这种形式的写法在参数类型是字符串的时候是没有问题的,但是参数类型为非字符串类型的时候就需要写成

<if test="username != null and 'hello'.toString() == username.toString()"></if>

mybatis对于字符串的相等不相等的判断也是有对应的特俗操作符

if的条件判断test是支持对象自身方法调用的,即使是自己写的方法

例如:里面可以用‘xxxx’.equals(xxxx) 字符串的比较两个字符串方法

xxxx.indexOf('ss') 判断字符串里面是否包含某个字符等等

  1. 判断list是否为空

if条件判断可以直接调用对象自身的方法进行逻辑判断,所以list判空。可以调用.size()>0或者.isEmpty()

例如:

<if test="userList != null and userList.isEmpty()"></if> 
或者
<if test="userList != null and userList.size()>0"></if>
  1. map参数同同理 取值的话 map.key(map中的key名字)即可

if标签判断数字相等"=="

判断的字段是Integer类型

query类:

public class Query{

    /**
     * 条件
     */
    private Integer a;

}

下面两种都可以:

<select id="countTable" resultType="java.lang.Long">
  select count(*) from table_name 
   <where>
      <if test="a == 3">
            and A = #{a}
      </if>
  </where>
</select> 
<select id="countTable" resultType="java.lang.Long">
  select count(*) from table_name 
   <where>
      <if test="a == '3'.toString()">
            and A = #{a}
      </if>
  </where>
</select> 

判断的字段是String类型

  • 如果这个字段的值是数字,那么和Integer类型是一样的,3 或者 ‘3’.toString() 都可以,但是 ‘3’ 不行
  • 如果这个字段的值不是数字,比如: “y” ,那么就要这样写:‘y’.toString()

query类:

public class Query{

    /**
     * 条件
     */
    private String a;
}

sql:

<select id="countTable" resultType="java.lang.Long">
  select count(*) from table_name 
   <where>
      <if test="a == '3'.toString()">
            and A = #{a}
      </if>
     <if test="a != null and a != '3'.toString()">
            and B = #{a}
     </if>
  </where>
</select> 

trim标签

trim标签语法

<trim prefix="" suffix="" suffixOverrides="" prefixOverrides=""></trim>

prefix:在trim标签内sql语句加上前缀。
suffix: 在trim标签内sql语句加上后缀。
suffixOverrides:指定去除多余的后缀内容,如:suffixOverrides=",",去除trim标签内sql语句多余的后缀","。
prefixOverrides: 指定去除多余的前缀内容

往购物车表中插入数据的mybatis语句

<insert id="insert" parameterType="com.tortuousroad.groupon.cart.entity.Cart">
        insert into cart
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="id != null">
                id,
            </if>
            <if test="userId != null">
                user_id,
            </if>
            <if test="dealId != null">
                deal_id,
            </if>
            <if test="dealSkuId != null">
                deal_sku_id,
            </if>
            <if test="count != null">
                count,
            </if>
            <if test="createTime != null">
                create_time,
            </if>
            <if test="updateTime != null">
                update_time,
            </if>
        </trim>
        <trim prefix="values (" suffix=")" suffixOverrides=",">
            <if test="id != null">
                #{id,jdbcType=BIGINT},
            </if>
            <if test="userId != null">
                #{userId,jdbcType=BIGINT},
            </if>
            <if test="dealId != null">
                #{dealId,jdbcType=BIGINT},
            </if>
            <if test="dealSkuId != null">
                #{dealSkuId,jdbcType=BIGINT},
            </if>
            <if test="count != null">
                #{count,jdbcType=INTEGER},
            </if>
            <if test="createTime != null">
                #{createTime,jdbcType=TIMESTAMP},
            </if>
            <if test="updateTime != null">
                #{updateTime,jdbcType=TIMESTAMP},
            </if>
        </trim>
    </insert>

没有指定suffixOverrides=","

拼接的sql语句为:

insert into cart (id,user_id,deal_id,) values(1,2,1,);

括号中多了个","符号,语法错误。

指定suffixOverrides=","

拼接的sql语句为:

insert into cart (id,user_id,deal_id,) values(1,2,1);

多余的","被去掉了,语法正确。

参考文章

https://blog.csdn.net/wang_luwei/article/details/122038039

posted @ 2024-04-12 15:01  大彪哥55  阅读(12)  评论(0编辑  收藏  举报