MySQL动态SQL基本使用

什么是动态SQL:动态SQL就是指根据不同的条件生成不同的SQL语句

利用动态SQL这一特性可以彻底摆脱JDBC之前拼接sql的痛苦

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

使用动态 SQL 并非一件易事,但借助可用于任何 SQL 映射语句中的强大的动态 SQL 语言,MyBatis 显著地提升了这一特性的易用性。

如果你之前用过 JSTL 或任何基于类 XML 语言的文本处理器,你对动态 SQL 元素可能会感觉似曾相识。在 MyBatis 之前的版本中,需要花时间了解大量的元素。借助功能强大的基于 OGNL 的表达式,MyBatis 3 替换了之前的大部分元素,大大精简了元素种类,现在要学习的元素种类比原来的一半还要少

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

例子一:

     <!--添加语句-->
    <insert id="addBlog"  parameterType="blog">
        insert into mybatis.blog (id,title,author,create_time,views)
        values(#{id},#{title},#{author},#{createTime},#{views})
    </insert>


    <!--需求:传title的时候按照title查 传author的时候按照author查 什么都不传查所有的-->
    <select id="queryBlogIF" parameterType="map" resultType="blog">
        select * from mybatis.blog
        <!--test必填 test里面写表达式:判断一些东西-->
        <where>
        <if test="title != null"><!--如果title不为空把这句话加上去-->
             and title = #{title}
        </if>
        <if test="author != null">
            and author = #{author}
        </if>
        </where>
    </select>



    <select id="queryBlogChoose" resultType="blog" parameterType="map">
        select * from mybatis.blog
        <where>
           <choose>
               <when test="title!=null">
                   title = #{title}<!--第一个语句不用加and 后面的要加 如果第一个不成立 由于有where的存在 会自动把and去掉-->
               </when>
               <when test="author!=null">
                   and author = #{author}
               </when>
               <otherwise>
                   and views = #{views}<!--如果两个条件都不成立执行这个-->
               </otherwise>
           </choose>
        </where>
    </select>




    <update id="updateBlog" parameterType="map" ><!--基本类型不用写resultType update里不需要-->
        update  mybatis.blog
        <set>
            <if test="title!=null">
                title = #{title},
            </if>
            <if test="author!=null">
                author = #{author}
            </if>
        </set>
        where id = #{id}



        <trim prefix="WHERE" prefixOverrides="AND |OR ">
            ...
        </trim>
        <!--前缀覆盖什么 后缀覆盖什么-->
        <trim prefix="" prefixOverrides="" suffix="" suffixOverrides="">

        </trim>
    </update>

IF

<select id="queryBlogIF" parameterType="map" resultType="blog">
    <!--如果不传入title或者author 那么将执行select * from mybatis.blog where 1=1-->
    select * from mybatis.blog where 1=1
    <!--test必填 test里面写表达式:判断一些东西-->
    <if test="title != null"><!--如果title不为空把这句话加上去-->
        and title = #{title}
    </if>
    <if test="author != null">
        and author = #{author}
    </if>
</select>
<!--例:如果穿了一个title和author去查询 sql会自动拼接为
select * from mybatis.blog WHERE title = ? and author = ?
传单个参数同理-->

优化

<!--需求:传title的时候按照title查 传author的时候按照author查 什么都不传查所有的-->
    <select id="queryBlogIF" parameterType="map" resultType="blog">
        select * from mybatis.blog
        <!--test必填 test里面写表达式:判断一些东西-->
        <where>
        <if test="title != null"><!--如果title不为空把这句话加上去-->
             and title = #{title}
        </if>
        <if test="author != null">
            and author = #{author}
        </if>
        </where>
    </select>

choose(when,otherwise)

有时候,我们不想使用所有的条件,而只是想从多个条件中选择一个使用。针对这种情况,MyBatis 提供了 choose 元素,它有点像 Java 中的 switch 语句。
还是上面的例子,但是策略变为:传入了 “title” 就按 “title” 查找,传入了 “author” 就按 “author” 查找的情形。若两者都没有传入,就返回标记为 featured 的 BLOG(这可能是管理员认为,与其返回大量的无意义随机 Blog,还不如返回一些由管理员精选的 Blog)。
 <select id="queryBlogChoose" resultType="blog" parameterType="map">
        select * from mybatis.blog
        <where>
           <choose>
               <when test="title!=null">
                   title = #{title}<!--第一个语句不用加and 后面的要加 如果第一个不成立 由于有where的存在 会自动把and去掉-->
               </when>
               <when test="author!=null">
                   and author = #{author}
               </when>
               <otherwise>
                   and views = #{views}<!--如果两个条件都不成立执行这个-->
               </otherwise>
           </choose>
        </where>
    </select>

<!--=====================================================================================-->
<!--不加where 如果没有匹配的条件,最终SQL会变成 
SELECT * FROM BLOG WHERE会导致查询失败
比如如果匹配的只是第二个条件 SQL会变成
SELECT * FROM BLOG WHERE AND title like ‘someTitle’
这个查询也会失败 这个问题不能简单地用条件元素来解决
MyBatis 有一个简单且适合大多数场景的解决办法
而这,只需要一处简单的改动 加where-->
select * from mybatis.blog
<where>
    <if test="title != null">
        title = #{title}
    </if>
    <if test="author != null">
        and author = #{author}
    </if>
</where>

trim(where,set)

用于动态更新语句的类似解决方案叫做 setset 元素可以用于动态包含需要更新的列,忽略其它不更新的列

set 元素会动态地在行首插入 SET 关键字,并会删掉额外的逗号(这些逗号是在使用条件语句给列赋值时引入的)

 <update id="updateBlog" parameterType="map" ><!--基本类型不用写resultType update里不需要-->
        update  mybatis.blog
        <set>
            <if test="title!=null">
                title = #{title},
            </if>
            <if test="author!=null">
                author = #{author}
            </if>
        </set>
        where id = #{id}
    </update>
<!--sql会自动拼接为:
update mybatis.blog SET title = ?, author = ? where id = ?-->

2.1动态SQL:if+where 语句

<select id="selectUserByUsernameAndSex" resultType="User" parameterType="User">
    select * from user
    <where>
        <if test="username != null">
            and username=#{username}
        </if>
        <if test="sex != null">
             and sex=#{sex}
        </if>
    </where>
</select>

2.2 动态SQL:choose(when,otherwise) 语句 (了解)

    <select id="selectUserByChoose" resultType="User" parameterType="User">
        select * from user
        <where>
            <choose>
                <when test="id !='' and id != null">
                    and id=#{id}
                </when>
                <when test="username !='' and username != null">
                    and username=#{username}
                </when>
                <otherwise>
                    and sex=#{sex}
                </otherwise>
            </choose>
        </where>
    </select>

2.3 动态SQL:trim 语句 (了解)

<select id="selectUserByUsernameAndSex" resultType="user" parameterType="User">
   select * from user
   <trim prefix="where" prefixOverrides="and | or">
       <if test="username != null">
           and username=#{username}
       </if>
       <if test="sex != null">
           and sex=#{sex}
       </if>
   </trim>
</select>
    <!-- 根据 id 更新 user 表的数据 -->
    <update id="updateUserById" parameterType="User">
        update user u
        <trim prefix="set" suffixOverrides=",">
            <if test="username != null and username != ''">
                u.username = #{username},
            </if>
            <if test="sex != null and sex != ''">
                u.sex = #{sex},
            </if>
        </trim>
        where id=#{id}
    </update>

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值