MYBATIS---动态SQL

抽空总结下mybatis中的动态SQL标签,加深下记忆

1.if 标签

常用于进行条件判断, test 属性用于指定判断条件。在不确定查询条件是否为空时,可以用 if 标签进行检查。假设有如下语句:

 SELECT  name, age
    FROM person
    WHERE name = #{name} and age = #{age}

在我们写死的情况下如果传入的name或者age为null的情况下会报错,这并不是我们想看到的,这个时候我们就可以使用if进行条件过滤动态的完成SQL语句拼接。

 select  name, age
    from person
    where 1=1
    <if test="name != null and pname != '' ">
        and name = #{pname}
    </if>
    <if test="age != null and age != 0 ">
        and age&lt; #{page}
    </if>

下面需要注意下,1.在xml的sql语句中,不能直接用大于号、小于号要用转义字符如果用小于号会报错误如下:org.apache.ibatis.builder.BuilderException: Error creating document instance. Cause: org.xml.sax.SAXParseException: The content of elements must consist of well-formed character data or markup.

   &lt;---<
   &gt;--->
   &amp;---&
   &apos;---'单引号     
   &quot;---"双引号      

2.<![CDATA[ ]]>标记的sql语句中的 等标签不会被解析,<!CDATA[]>是xml语法.在CDATA内部的所有内容会被解析器忽略.如果包含了很多的"<“字符<=和”&"字符–就像程序代码一样,最好把他们都放在CDATA部件中.

3.where 后的 1 = 1 建议加上,这样可以避免无一条件满足时,最终的 SQL 语句中 where 后面没有过滤条件。

2.where - if 标签标签

在 SELECT 语句中,为了简化 if 标签,可以使用 where - if 标签组合使用:元素只会在至少有一个子元素的条件返回 SQL 子句的情况下才去插入“WHERE”子句。如果没有条件, 不会生成 where 关键字。如果有条件, 会自动添加 where 关键字。 如果第一个条件中有 and, 自动去除之

 selectid, name, age
  from person
 
  <where>
      <if test="pname != null and pname != '' ">
          and name = #{pname}
      </if>
      <if test="page != null and page != 0 ">
          and age &lt; #{page}
      </if>
  </where>

3.set - if 标签

在 UPDATE 语句中,为了简化 if 标签,可以使用 set - if 标签组合使用

update person
    <set>
        <if test="pname != null and pname != '' ">
            name = #{pname}
        </if>
        <if test="page != null and page != 0 ">
            and age = #{page}
        </if>
    </set>
    where id = #{pid}

4.trim - if 标签

trim标签 一般用于去除sql语句中多余的and关键字,逗号,或者给sql语句前拼接 “where“、“set“以及“values(“ 等前缀,或者添加“)“等后缀,可用于选择性插入、更新、删除或者条件查询等操作。它是一种更强大的组合标签,它既可以处理 SELECT语句,又可以处理 UPDATE 语句。如代替上面的 where - if 标签:

 SELECT id,name, age
    FROM person
 
    <trim prefix="WHERE" prefixOverrides="AND|OR">
        <if test="pname != null and pname != '' ">
            name = #{pname}
        </if>
        <if test="page != null and page != 0 ">
            age &lt; #{page}
        </if>
    </trim>

代替 set - if 标签:

 UPDATE person
    <trim prefix="SET" prefixOverrides=",">
        <if test="pname != null and pname != '' ">
            name = #{pname}
        </if>
        <if test="page != null and page != 0 ">
            age &lt; #{page}
        </if>
    </trim>
    WHERE id = #{pid}

5.choose标签

有时候我们并不想应用所有的条件,而只是想从多个选项中选择一个。MyBatis提供了choose 元素,按顺序判断when中的条件出否成立,如果有一个成立,则choose结束。当choose中所有when的条件都不满则时,则执行 otherwise中的sql。类似于Java 的switch 语句,choose为switch,when为case,otherwise则为default。if是与(and)的关系,而choose是或(or)的关系。

 SELECT id, name, age
    FROM person
 
    <where>
        <choose>
            <when test="pname != null and pname != '' ">
                name = #{pname}
            </when>
            <when test="page != null and page != 0 ">
                AND age &lt; #{page}
            </when>
            <otherwise>
 
            </otherwise>
        </choose>
    </where>

6.foreach标签

对于动态 SQL 非常必须的,主是要迭代一个集合,通常是用于 IN 条件。List 实例将使用 “list” 做为键,数组实例以 “array” 做为键。

foreach 元素是非常强大的,它允许你指定一个集合,声明集合项和索引变量,它们可以用在元素体内。它也允许你指定开放和关闭的字符串,在迭代之间放置分隔符。这个元素是很智能的,它不会偶然地附加多余的分隔符。

注意:可以传递一个List实例或者数组作为参数对象传给是MyBatis。当你这么做的时候,MyBatis 会自动将它包装在一个 Map中,用名称在作为键。List 实例将会以 “list” 作为键,而数组实例将会以 “array” 作为键。

collection:为集合名
item :表示集合中每一个元素 进行迭代时的别名
index :指定一个名字,用于表示在迭代过程中,每次迭代到的位置
open :表示该语句以什么开始
separator: 表示在每次进行迭代之间以什么符号作为分隔 符
close :表示以什么结束

  select *
      from WXBHPT_V_Customers
      <where>
          <if test='ids!=null '>
              customid  in
              <foreach collection="ids" item="id" open="(" separator="," close=")" index="index">
                #{id}
              </foreach>
          </if>
      </where>
   order by customid;
  SELECT id, name, age
    FROM person
    WHERE id IN
 
    <foreach collection="array" item="pid" open="(" separator="," close=")">
      #{pid}
    </foreach>
  SELECT id, name, age
    FROM person
    WHERE id IN
 
    <foreach collection="list" item="pid" open="(" separator="," close=")">
        #{pid}
    </foreach>

7.bind标签

bind标签用于在SQL执行的上下文中绑定一个变量,方便在后续中直接使用:下面的例子中将name参数拼接成模糊查询需要的字符串然后和bindName绑定,在后面的使用中可以直接使用bindName变量名称引用这个模糊字符串.在进行模糊查询时,如果使用“${}”拼接字符串,则无法防止 SQL 注入问题。如果使用字符串拼接函数或连接符号,但不同数据库的拼接函数或连接符号不同。例如 MySQL 的 concat 函数、Oracle 的连接符号“||”,这样 SQL 映射文件就需要根据不同的数据库提供不同的实现,显然比较麻烦,且不利于代码的移植。幸运的是,MyBatis 提供了 元素来解决这一问题。

<!--使用bind元素进行模糊查询-->
<select id="selectUserByBind" resultType="com.po.MyUser" parameterType= "com.po.MyUser">
    <!-- bind 中的 uname 是 com.po.MyUser 的属性名-->
    <bind name="paran_uname" value="'%' + uname + '%'"/>
        select * from user where uname like #{paran_uname}
</select>

8.SQL和include标签

如果一些sql片段反复出现,就可以使用SQL和include标签把这块抽取出来复用。include 还可以自定义一些属性 sql标签内部可以使用这些自定义的属性 取值使用${} 而不是#{}以后后者是取参数的

<insert id="insertTeachers">
    insert into teachers(
    <include refid="column">
    <property name="id" value="school_id"/>
    </include>
    )  values
    <foreach collection="list" item="item" separator=",">
        (#{item.name},#{item.teacher_gender},#{item.student.id})
    </foreach>
    </insert>

    <sql id="column">
    name,gender,${id}
    </sql>
发布了29 篇原创文章 · 获赞 11 · 访问量 1865

猜你喜欢

转载自blog.csdn.net/chihaihai/article/details/102414930