您的位置:首页 > 数据库

mybatis 动态SQL

2018-01-13 17:29 316 查看
一、前言

       MyBatis的强大特性之一就是它的动态SQL。在实际项目开发中,经常需要根据不同条件拼接SQL语句,拼接时不能忘记必要的空格,有时候还要注意省略掉列名列表最后的逗号,等等。在使用JDBC或其他类似持久层框架操作数据库时,处理这种情况是非常麻烦的,甚至可以用痛苦来形容,而在MyBatis中利用动态SQL这一特性可以很简单地解决这个问题。

      动态SQL元素和使用JSTL其他类似基于XML的文本处理器相似,mybatis采用功能强大的基于OGNL(Object-Graph Navigation Language)的表达式来完成动态SQL。OGNL表达式可以被用在任意的SQL映射语句中。

二、常见的动态SQL元素

      常见的动态SQL元素包括:

      if、 choose(when、otherwise)、 where、set、foreach、bind

     1、if用法

       if标签通常用于WHERE语句中,通过判断参数值来决定是否使用某个查询条件,它也经常用于UPDATE语句中判断是否更新某一字段,还可以在INSERT语句中用来判断是否插入某个字段的值。

      if标签有一个必填的属性test,test的属性值是一个如何OGNL要求的判断表达式,表达式的结果可以是true或false,除此之外所有的非0值都为true,只有0位false。为了方便理解,在表达式中,建议只使用true或false作为结果。

       ①判断条件property!=null 或property==null;适用于任何类型的字段,用于判断属性值是否为空。

       ②判断条件property!=' '或property==' ';仅适用于String类型的字段,用于判断是否为空字符串。

       ③当有多个判断条件时,使用and或or进行连接,嵌套的判断可以使用小括号分组。

       在UPDATE更新列中使用if,只更新有变化的字段,需要注意的是更新的时候不能将原来有值但没有发生变化的字段更新为空或为null,通过if标签可以实现这种动态列更新。

        在INSERT动态插入列中使用if,若在列的部分增加if条件,则values的部分也要增加相同的if条件,必须保证上下可以互相对应,完全匹配。

        2、choose用法

       if标签提供了基本的条件判断,但是它无法实现if...else的逻辑,要想实现这样的逻辑,就需要用到choose   when   otherwise标签。它有点类似于Java中的switch语句。choose元素中包含when和otherwise标签,一个choose中至少有一个when,至多有1个otherwise。

        3、where、set、trim用法

        这三个标签解决了类似的问题,并且where和set都属于trimj的一种具体用户。下面分别来看这3个标签。

3.1、where用法

        where标签的作用:只有在至少一个以上的if条件有值的情况下才去插入WHERE子句。并且,如果where后面的字符串是以AND和OR开头的,就将他们剔除。

3.2、set用法

        set标签的作用:如果该标签包含的元素中有返回值,就插入一个set;如果set后面的字符串是以逗号结尾的,就将这个逗号剔除。

3.3、trim用法

        where和set标签的功能都可以用trim标签来实现,并且在底层就是通过TrimSQLNode实现的。

       where标签对应trim的实现如下:

<trim prefix="WHERE" prefixOverrides="AND |OR ">
...
</trim>      set标签对应的trim实现如下:
 <trim prefix="SET" prefixOverrides=",">
...
</trim>trim标签有如下属性:
     ①prefix:当trim元素内包含内容时,会给内容增加prefix指定的前缀。

     ②prefixOverrides:当trim元素内包含内容时,会把内容中匹配的前缀字符串去掉。

     ③suffix:当trim元素内包含内容时,会给内容增加suffix指定的后缀。

     ④suffixOverrides:当trim元素内包含内容时,会把内容中匹配的后缀字符串去掉。

4、foreach用法

      SQl语句中有时会使用IN关键字,例如id  in (1,2,3)。这时需要配合使用foreach标签来满足需求。

      foreach标签可以对容器类(数组、Map、或实现了Iterable接口(如List、Set))的对象进行遍历,数组在处理时会转换成List对象,因此foreach遍历的对象可以分为两大类:Iterable类型和Map类型。

      4.1foreach实现in集合

      foreach实现in集合(或数组)是最简单和常用的一种情况。forach包含以下属性。

      ①collection:必填,值为要迭代循环的属性名。

      ②item:变量名,值为迭代对象中取出的每一个值

      ③index:索引的属性名,在集合数组情况下值为当前的索引值,当迭代循环的对象是Map类型时,这个值为Map的key(键值)

      ④open:整个循环内容开头的字符串

      ⑤close:整个循环内容结尾的字符串。

      ⑥separator:每次循环的分隔符

5、bing用法

      bind标签可以使用OGNL表达式创建一个变量并将其绑定到上下文中。bind标签的两个属性都是必选项。name为绑定到上下文的变量名,value为OGNL表达式。创建一个bind标签的变量后,就可以在下面直接使用,使用bind拼接字符串不仅可以避免更换数据库而修改SQL,也能预防SQL注入。

      如在模糊查询中:

<bind name="_stringLike" value="'%'+stringLike+'%'"/>

      

   

      

       
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: