MyBatis的动态SQL

动态SQL

开发人员在使用JDBC或其他类似的框架进行数据库开发时,通常都要根据需求去手动拼装SQL,这是一个非常麻烦且痛苦的工作,
而MyBatis提供的对SQL语句动态组装的功能,恰能很好的解决这一麻烦工作。

动态SQL是MyBatis的强大特性之一,MyBatis3采用了功能强大的基于OGNL的表达式来完成动态SQ

<if>元素

 在MyBatis中,<if>元素是最常用的判断语句,它类似于Java中的if语句,主要用于实现某些简单的条件选择。其基本使用示例如下:  

   <!--使用<if>元素对username和jobs进行非空判断,并动态组装SQL-->
     select * from t_customer where 1=1 
     <if test="username !=null and username !=''">
        and username like concat('%',#{username}, '%')
     </if>
     <if test="jobs !=null and jobs !=''">
        and jobs= #{jobs}
     </if>

<choose>、<when>、<otherwise>元素 

在MyBatis如果条件过多,这时就不适合使用If,这种情况显然更适合使用switch…case…default语句来处理,而在SQL中就可以使用<choose><when><otherwise>元素组合进行处理。其基本使用示例如代码所示:

      <!--使用<choose>及其子元素依次对条件进行非空判断,并动态组装SQL-->
      select * from t_customer where 1=1
      <choose>
           <when test="username !=null and username !=''">
                       and username like concat('%',#{username}, '%')
           </when>
           <when test="jobs !=null and jobs !=''">
                       and jobs= #{jobs}
           </when>
           <otherwise>
                   and phone is not null
           </otherwise>
      </choose>

<where>、<trim>元素

 针对“where 1=1”,在MyBatis的SQL中就可以使用<where>或<trim>元素进行动态处理。

<where>元素处理  

       <where>会自动判断SQL语句,只有<where>内的条件成立时,才会在拼接SQL中加入where关键字,否则将不会添加;还会去除多余的“AND”或“OR

<trim>元素处理

       <trim>的作用是去除特殊的字符串,它的prefix属性代表语句的前缀,prefixOverrides属性代表需要去除的哪些特殊字符串,功能和<where>基本是等效的。

      select * from t_customer
      <where>
           <if test="username !=null and username !=''">
                 and username like concat('%',#{username}, '%')
           </if>
           <if test="jobs !=null and jobs !=''">
                 and jobs= #{jobs}
           </if>
      </where>
     select * from t_customer
     <trim prefix="where" prefixOverrides="and">
            <if test="username !=null and username !=''">
                  and username like concat('%',#{username}, '%')
            </if>
            <if test="jobs !=null and jobs !=''">
                  and jobs= #{jobs}
            </if>
     </trim>

 <set>元素

动态更新某个对象的指定字段

<!--使用<set>和<if>元素对username和jobs进行更新判断,并动态组装SQL。这样就只需要传入想要更新的字段即可-->

  <update id="updateCustomer"  parameterType="com.po.Customer">
        update t_customer 
        <set>
            <if test="username !=null and username !=''">
                  username=#{username},
            </if>
            <if test="jobs !=null and jobs !=''">
                  jobs=#{jobs},
            </if>
        </set>
        where id=#{id}
</update>

<foreach>元素

在面对数量比较大的查询时,挑选指定条件的数据

      <select id="findCustomerByIds" parameterType="List"
                         resultType="com.po.Customer">
           select * from t_customer where id in
            <foreach item="id" index="index" collection="list" 
                            open="(" separator="," close=")">
                   #{id}
            </foreach>
     </select>

<foreach>元素中使用的几种属性的描述具体如下
        index:配置的是当前元素在集合的位置下标。
        collection:配置的list是传递过来的参数类型(首字母小写),它可以是一个array、list(或collection)、Map集合的键、POJO包装类中数组或集合类型的属性名等。
        open和close:配置的是以什么符号将这些集合元素包装起来。
        separator:配置的是各个元素的间隔符。

在使用<foreach>时最关键也是最容易出错的就是collection属性,该属性是必须指定的,而且在不同情况下,该属性的值是不一样的。主要有以下3种情况:
        如果传入的是单参数且参数类型是一个数组或者List的时候,collection属性值分别为array和list(或collection)。
        如果传入的参数是多个的时候,就需要把它们封装成一个Map了,当然单参数也可以封装成Map集合,这时候collection属性值就为Map的键。
        如果传入的参数是POJO包装类的时候,collection属性值就为该包装类中需要进行遍历的数组或集合的属性名。

<bind>元素

在处理模糊查询时,最初使用的是        select * from t_customer where username like '%${value}%'
但是这样做的缺点如下:
        如果使用“${}”进行字符串拼接,则无法防止SQL注入问题;
        如果改用concat函数进行拼接,则只针对MySQL数据库有效;
        如果改用“||”进行字符串拼接,则只针对Oracle数据库有效。
这样,映射文件中的SQL就要根据不同的情况提供不同形式的实现,这显然是比较麻烦的,且不利于项目的移植。
为了减少这种麻烦,就可以使用MyBatis的<bind>元素来解决这一问题。

  <select id="findCustomerByName" parameterType="com.po.Customer"  resultType="com.po.Customer">
          <!--_parameter.getUsername()表示传递进来的参数(也可以直接写成对应的参数变量名,如username)-->
          <bind name="pattern_username" value="'%'+_parameter.getUsername()+'%'" />
           select * from t_customer 
           where 
           <!--需要的地方直接引用<bind>元素的name属性值即可-->
           username like #{pattern_username}
     </select>

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员路同学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值