zoukankan      html  css  js  c++  java
  • Mybatis基于XML配置SQL映射器(三)

    Mybatis之动态SQL

    mybatis 的动态sql语句是基于OGNL表达式的。可以方便的在 sql 语句中实现某些逻辑. 总体说来mybatis 动态SQL 语句主要有以下几类:

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

    if

    动态 SQL 通常要做的事情是有条件地包含 where 子句的一部分。

    1   <select id="selectUserByOrgid"  resultType="java.util.HashMap">
    2         select  username,password from sys_user where org_id = #{orgid,jdbcType=VARCHAR}
    3         <if test="orderFiled != null" >
    4             order by  ${orderFiled}
    5             <if test="orderSort != null" >
    6                 ${orderSort}
    7             </if>
    8         </if>
    9     </select>
    View Code

    choose, when, otherwise

    有些时候,我们不想用到所有的条件语句,而只想从中择其一二。针对这种情况,MyBatis 提供了 choose 元素,它有点像 Java 中的 switch 语句。

     1  <select id="selectByUsernameORorg" parameterType="java.lang.String" resultMap="BaseResultExtMap">
     2         select
     3         <include refid="Base_Ext_Column_List" />
     4         from sys_user
     5         where
     6         <choose>
     7           <when test="username != null">
     8             AND username like#{username,jdbcType=VARCHAR}
     9           </when>
    10           <when test="name != null ">
    11             AND name like #{name,jdbcType=VARCHAR}
    12           </when>
    13           <otherwise>
    14             AND org_id =#{orgid,jdbcType=VARCHAR}
    15           </otherwise>
    16         </choose>
    17     </select>
    View Code

    trim, where, set

    前面几个例子已经合宜地解决了一个臭名昭著的动态 SQL 问题。为了解决前面SQL可能出现的问题,就是使用where标签改写。where标签非常智能。如果标签内部没有合适的语句,where标签就不会生成任何东西,防止出现错误语句。

     1 <select id="selectByUsernameORorg2" parameterType="java.lang.String" resultMap="BaseResultExtMap">
     2         select
     3         <include refid="Base_Ext_Column_List" />
     4         from sys_user
     5         <where>
     6             <if test="name != null">
     7                 name = #{name,jdbcType=VARCHAR}
     8             </if>
     9             <if test="username != null">
    10                 AND username like #{username,jdbcType=VARCHAR}
    11             </if>
    12         </where>
    13     </select>
    View Code

    有时候where标签还不能满足需求。这时候还可以使用trim标签进行更高级的定制。trim标签中的prefix和suffix属性会被用于生成实际的SQL语句,会和标签内部的语句拼接。如果语句的前面或后面遇到prefixOverrides或suffixOverrides属性中指定的值,MyBatis会自动将它们删除。在指定多个值的时候,别忘了每个值后面都要有一个空格,保证不会和后面的SQL连接在一起。下面这个例子和where标签完全等效。

    1 <trim prefix="WHERE" prefixOverrides="AND |OR ">
    2   ... 
    3 </trim>
    View Code

    类似的用于动态更新语句的解决方案叫做 set。set 元素可以被用于动态包含需要更新的列,而舍去其他的。

     1 <update id="updateByPrimaryKeySelective" parameterType="com.goku.mybatis.model.sysUser">
     2     <!--
     3       WARNING - @mbg.generated
     4       This element is automatically generated by MyBatis Generator, do not modify.
     5     -->
     6     update sys_user
     7     <set>
     8       <if test="username != null">
     9         username = #{username,jdbcType=VARCHAR},
    10       </if>
    11       <if test="password != null">
    12         password = #{password,jdbcType=VARCHAR},
    13       </if>
    14       <if test="name != null">
    15         name = #{name,jdbcType=VARCHAR},
    16       </if>
    17       <if test="sex != null">
    18         sex = #{sex,jdbcType=VARCHAR},
    19       </if>
    20       <if test="status != null">
    21         status = #{status,jdbcType=CHAR},
    22       </if>
    23       <if test="orgId != null">
    24         org_id = #{orgId,jdbcType=VARCHAR},
    25       </if>
    26       <if test="email != null">
    27         email = #{email,jdbcType=VARCHAR},
    28       </if>
    29       <if test="idcard != null">
    30         idcard = #{idcard,jdbcType=VARCHAR},
    31       </if>
    32       <if test="isAdmin != null">
    33         is_admin = #{isAdmin,jdbcType=VARCHAR},
    34       </if>
    35       <if test="sort != null">
    36         sort = #{sort,jdbcType=BIGINT},
    37       </if>
    38       <if test="mobile != null">
    39         mobile = #{mobile,jdbcType=VARCHAR},
    40       </if>
    41       <if test="stationid != null">
    42         stationid = #{stationid,jdbcType=LONGVARCHAR},
    43       </if>
    44     </set>
    45     where id = #{id,jdbcType=VARCHAR}
    46   </update>
    View Code

    这里,set 元素会动态前置 SET 关键字,同时也会消除无关的逗号,因为用了条件语句之后很可能就会在生成的赋值语句的后面留下这些逗号。

    若你对等价的自定义 trim 元素的样子感兴趣,那这就应该是它的真面目:

    1 <trim prefix="SET" suffixOverrides=",">
    2   ...
    3 </trim>
    View Code

    foreach

    动态 SQL 的另外一个常用的必要操作是需要对一个集合进行遍历,通常是在构建 IN 条件语句的时候

    1  <select id="selectUserByOrgid2"  resultType="java.util.HashMap">
    2         select  username,password from sys_user where org_id  IN
    3         <foreach item="item" index="index" collection="list"
    4                  open="(" separator="," close=")">
    5             #{item}
    6         </foreach>
    7     </select>
    View Code

    bind

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

    1  <select id="selectByUsername2" parameterType="java.lang.String" resultMap="BaseResultExtMap">
    2         <bind name="username" value="'%' + username + '%'" />
    3         select
    4         <include refid="Base_Ext_Column_List" />
    5         from sys_user
    6         where username LIKE #{username}
    7     </select>
    View Code

    GITHUB

    github :  https://github.com/nbfujx/learn-java-demo/tree/master/Goku.MybatisDemo.XML

  • 相关阅读:
    Windowsforms 中对文件操作
    ADO.net增删改的使用
    ADO.net数据访问
    可空类型
    FineUI 页面跳转
    ASP.NET页面之间传递值的几种方式
    C# Find() 与 FindAll()方法的使用
    在Sql中将 varchar 值 '1,2,3,4,5,6' 转换成数据类型 int
    DataSet、DataTable、DataRow、DataColumn区别及使用实例
    C#中如何排除/过滤/清空/删除掉字符串数组中的空字符串
  • 原文地址:https://www.cnblogs.com/nbfujx/p/7717784.html
Copyright © 2011-2022 走看看