zoukankan      html  css  js  c++  java
  • 动态SQL的标签使用和入门写法

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

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

    if

    select * from user where 1=1 
    <if test="id != null and id != ''">
        and id = #{id}
    </if>
    <if test="name != null and name != ''">
        and name = #{name}
    </if>

    为什么使用1=1作为参数都很清楚了,如果没有1=1且条件if为true,那么拼接的sql语句会变成,是错误的拼接

    如果没有匹配又没有1=1的条件会怎么样?

    select * from user where

    如果匹配的只是第二个条件又会怎样?

    select * from user where and name = nameValue

    if的多条件使用,即使没有1=1也不会出现问题,因为此时有一个固定条件,只要确保不出现 where 和 and的连接的情况即可。

    <select id="findActiveBlogLike"
         resultType="Blog">
      SELECT * FROM BLOG WHERE state = ‘ACTIVE’
      <if test="title != null">
        AND title like #{title}
      </if>
      <if test="author != null and author.name != null">
        AND author_name like #{author.name}
      </if>
    </select>

    choose、when、otherwise

    <select id="testStudayChoose" resultType="User">
       select * from `user`
        <where>
            <choose>
                <when test="name != null and name != ''">
                    and name = #{name}
                </when>
                <when test="password != null and password != ''">
                    and password = #{password}
                </when>
                <otherwise>
                    and uid = 1
                </otherwise>
            </choose>
        </where>
    </select>

    下面会讲到<where>,其实就是代替了where 1=1。

    值得注意的是choose标签相当于switch,满足第一个条件以后就不会执行其他语句拼接,例如name和password两个参数都传也只会执行name。

    而otherwise标签则是相当于default当条件都不满足时执行的拼接sql。

    trim、where、set

    <where> </where>

    前面几个例子已经合宜地解决了一个臭名昭著的动态 SQL 问题。现在回到之前的 “if” 示例,这次我们将 where 1=1 设置成动态条件

    <select id="findOneSql" resultType="User">
        select * from `user`
        <where>
            <if test="id != null and id != ''">
                and uid = #{uid}
            </if>
            <if test="birthday != null">
                and birthday = #{birthday}
            </if>
        </where>
    </select>

    where标签在if条件都不满足时取消的where的条件拼接,若子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除。

    trim标签也可以完成相同的功能

    <select id="findOneSql" resultType="User">
        select * from `user`
        <trim prefix="WHERE" prefixOverrides="AND |OR"> 
            <if test="id != null and id != ''">
                and uid = #{uid}
            </if>
            <if test="birthday != null">
                and birthday = #{birthday}
            </if>
        </trim>
    </select>

    值得注意的是trim标签中的每个属性

    属性描述
    prefix 给sql语句拼接的前缀
    suffix 给sql语句拼接的后缀
    prefixOverrides 去除sql语句前面的关键字或者字符,该关键字或者字符由prefixOverrides属性指定,假设该属性指定为"AND",当sql语句的开头为"AND",trim标签将会去除该"AND"
    suffixOverrides 去除sql语句后面的关键字或者字符,该关键字或者字符由suffixOverrides属性指定

    <set></set>

    <update id="updateOneSql">
        update `user`
        <set>
            <if test="name != null and name != ''">
                `name` = #{name},
            </if>
            <if test="birthday != null">
                birthday = #{birthday}
            </if>
        </set>
        where uid = #{uid}
    </update>
    <-- 或使用的写法 -->
    <
    trim prefix="SET" suffixOverrides=","> ... </trim>

    foreach 

    例如使用场景为 uid in () 括号中位多个条件

    <select id="setValueListSql" parameterType="java.util.List" resultType="User">
        SELECT * from `user` where uid in
        <foreach collection="list" open="(" separator="," close=")" item="item" index="index">
            #{item}
        </foreach>
    </select>
      • collection:表示传入过来的参数的数据类型。该参数为必选。要做 foreach 的对象,作为入参时,List 对象默认用 list 代替作为键,数组对象有 array 代替作为键,Map 对象没有默认的键。当然在作为入参时可以使用 @Param(“keyName”) 来设置键,设置 keyName 后,list,array 将会失效。 除了入参这种情况外,还有一种作为参数对象的某个字段的时候。举个例子:
        如果 User 有属性 List ids。入参是 User 对象,那么这个 collection = “ids” 如果 User 有属性 Ids ids;其中 Ids 是个对象,Ids 有个属性 List id;入参是 User 对象,那么 collection = “ids.id”
        • 如果传入的是单参数且参数类型是一个 List 的时候,collection 属性值为 list
        • 如果传入的是单参数且参数类型是一个 array 数组的时候,collection 的属性值为 array
        • 如果传入的参数是多个的时候,我们就需要把它们封装成一个 Map 了,当然单参数也可以封装成 map。
      • item: 循环体中的具体对象。支持属性的点路径访问,如 item.age,item.info.details。具体说明:在 list 和数组中是其中的对象,在 map 中是 value,该参数为必选。(它是每一个元素进行迭代时的别名)
      • index:在 list 和数组中,index 是元素的序号;在 map 中,index 是元素的 key。
      • open:表示该语句以什么开始
      • close:表示该语句以什么结束
      • separator:表示在每次进行迭代之间以什么符号作为分隔符

    补充

     在insert时使用foreach批量插入

    insert into user(id,name)
    values
    <foreach collection="list" separator=","  item="item" index="index">
            (#{item.id},#{item.name})
    </foreach>
  • 相关阅读:
    点赞
    js点击事件,数字累加
    html中hr的各种样式使用
    基于Bootstrap垂直响应的jQuery时间轴特效
    bootstrop日历
    前端经验
    bootstrop登陆页面
    bootstrop设置背景图片自适应屏幕
    建立博客的第一天
    php伪静态--隐藏地址实际路径方法
  • 原文地址:https://www.cnblogs.com/xiaozhang666/p/13503611.html
Copyright © 2011-2022 走看看