zoukankan      html  css  js  c++  java
  • SSM-动态SQL

    SSM-动态SQL

    动态SQL主要是解决同一类SQL语句匹配不同的问题,举个栗子:

    加入我要执行一个查询语句,但是是一个不确定的查询语句,可能会根据ID去查,如果ID没有就可能根据名字去查,或者说同时根据两个去查。那么这时候SQL语句就是不确定的,就要用到mybatis动态SQL语句了,同时Mybatis是基于OGNL表达式的。

    动态SQL语句

    • if
    • where
    • choose
      • when
      • otherwise
    • set
    • trim
    • foreach
    • sql
    • include
    • bind

    数据形式

    idthe_nameflower
    1 小明 小红花

    if

    if很简单的知道,就是判断条件的。
    xml映射文件配置文件

    <!--动态SQL if语句-->
    <select id="query1" resultType="com.weno.pojo.Girl">
        select * from Girl where
        <if test= "the_name != null">
            the_name = #{the_name}
        </if>
        <if test= "flower != null">
            and flower = #{flower};
        </if>
    </select>
    
    @Test
    public void m006() {
        SqlSession sqlSession = MybatisUtil.getSession();
    
        GirlMapper mapper = sqlSession.getMapper(GirlMapper.class);
    
        Girl g= new Girl();
    
        g.setName("小明");
        // g.setFlower("小红花");
        Girl girl=mapper.query1(g);
    
        sqlSession.commit();
        sqlSession.close();
        System.out.printf(girl.toString());
    }
    

    如果此时我们将小红花注释掉查看一下运行结果:

    DEBUG [main] - ==>  Preparing: select * from Girl where the_name = ? 
    DEBUG [main] - ==> Parameters: 小明(String)
    TRACE [main] - <==    Columns: id, the_name, flower
    TRACE [main] - <==        Row: 1, 小明, 小红花
    DEBUG [main] - <==      Total: 1
    

    在SQL语句中并没有加上flower语句。但是此时却有一个问题,如果the_namenull,而flower不为null,那么在SQL语句中岂不是多了一个and,变成了:

    DEBUG [main] - ==>  Preparing: select * from Girl where and flower = ?; 
    

    这时候程序肯定报错,那么我们该如何处理呢?那么接下来说一下where标签。

    where

    任然使用上面的例子:

    <select id="query2" resultType="com.weno.pojo.Girl">
        select * from Girl
        <where>
            <if test="the_name != null">
                and the_name = #{the_name}
            </if>
            <if test="flower != null">
                and flower = #{flower}
            </if>
        </where>
    </select>
    

    这个跟上面的区别就是将where改成了<where>标签。
    <where>在这里的作用就是当标签中有返回值时,就插入一个where,同时,如果标签是以ANDOR【不区分大小写】开头时,就剔除。

    choose

    choose语句有点类似Java中的switch,当有一个符合时,就选择那一个并跳出。
    映射文件

    <select id="query3" resultType="com.weno.pojo.Girl">
        select * from Girl where
        <choose>
            <when test="id != null and id!=''">
                id = #{id}
            </when>
            <when test="the_name != null and the_name != ''">
                the_name = #{the_name}
            </when>
    
            <otherwise>
                flower = #{flower}
            </otherwise>
        </choose>
    </select>
    

    在这种情况下,如果id符合的话,就不会再考虑下面的了。

    @Test
    public void m008() {
        SqlSession sqlSession = MybatisUtil.getSession();
        GirlMapper mapper = sqlSession.getMapper(GirlMapper.class);
        Girl g= new Girl();
        g.setId(1);
        g.setName("小明");
        g.setFlower("小红花");
        Girl girl=mapper.query3(g);
        sqlSession.commit();
        sqlSession.close();
        System.out.printf(girl.toString());
    }
    

    SQL语句,在其中并没有选择the_name

    DEBUG [main] - ==>  Preparing: select * from Girl where id = ? 
    

    set

    set是一个更新数据的标签

    <update id="update1">
        update Girl set the_name=#{the_name},flower=#{flower} where id=#{id};
    </update>
    

    java代码:

    @Test
    public void m009() {
        SqlSession sqlSession = MybatisUtil.getSession();
        GirlMapper mapper = sqlSession.getMapper(GirlMapper.class);
        Girl g= new Girl();
        g.setId(1);
        g.setName("小红");
    //        g.setFlower("小明花");
        mapper.update1(g);
        sqlSession.commit();
        sqlSession.close();
    }
    

    如果此时这样执行,那么在数据库表里面,flower的数据即为null。假如此时,使用if标签

    <update id="update2">
        update Girl set
        <if test="the_name != null and the_name != ''">
        the_name=#{the_name},
        </if>
        <if test="flower != null and flower != ''">
            flower=#{flower}
        </if>
        where id=#{id};
    </update>
    

    那么此时会出现一个问题,如果第一个符合,而第二个不符合,那么就会多一个,,此时使用<set>标签就可以解决这个问题

    <update id="update3">
        update Girl
        <set>
            <if test="the_name != null and the_name != ''">
                the_name=#{the_name},
            </if>
            <if test="flower != null and flower != ''">
                flower=#{flower},
            </if>
        </set>
        where id=#{id};
    </update>
    

    <set>标签和<where>有点类似,在<set>标签中,如果结尾有逗号,就将逗号去除。

    trim

    <trim>就很神奇了,它既可以实现<set>的功能,也能够实现<where>的功能。

    trim可以在前面增加和删除内容,也可在在后面也执行此操作。

    <update id="query0">
        <trim prefixOverrides="and | or">
            <if test="the_name != null">
                and the_name = #{the_name}
            </if>
            <if test="flower != null">
                and flower = #{flower}
            </if>
        </trim>
    </update>
    

    去除第一个and或则是or

    • prefix:前缀      
    • prefixoverride:去掉第一个a
    • suffix:后缀  
    • suffixoverride:去掉最后一个

    foreach

    foreach 类似for循环。

    改写我们用 foreach 来改写 select * from Girl where id in (1,2,3)

    映射文件

        <!-- collection:指定输入对象中的集合属性,使用@Param("ids")指令名字
            item:每次遍历生成的对象
            open:开始遍历时的拼接字符串
            close:结束时拼接的字符串
            separator:遍历对象之间需要拼接的字符串
            select * from Girl where id in (1,2,3) -->
    <select id="queryByIDs" resultType="com.weno.pojo.Girl">
        select * from Girl where
        <foreach collection="ids" item="id" open="id in (" close=" ) " separator=",">
                #{id}
        </foreach>
    </select>
    

    sql

    SQL片段主要是为了提高效率,可以讲动态SQL的判断部分独立处理,提高程序的复用率。

    <!-- id是sql片段的标识,一定要唯一 -->
    <sql id="sql_1"> 
      <if test="the_name != null and the_name != ''">
          the_name = #{the_name}
      </if>
    </sql>
    

    注意:在SQL片段中,不要包括where

    include

    引用SQL片段,使用上面的例子

    <select id="query2" resultType="com.weno.pojo.Girl">
        select * from Girl
        <where>
            <include refid="sql_1"/>
            <if test="flower != null">
                and flower = #{flower}
            </if>
        </where>
    

    就是如此简单。

    bind

    <bind>简单的来说,就是使值变成另外一个。

    例如在模糊查询语句中要使传入的值变成%*%,那么就使用bind进行连接。

    <select id="queryLikeByName" resultType="com.weno.pojo.Girl">
        select * from Girl
        <bind name="_name" value="'%'+the_name+'%'"/>
        <!-- 如果the_name代表A,那么_name则代表%A% -->
        where the_name like #{_name}
    </select>
    

    mybati的动态语句大概就这样了,如果学会了使用,那么毋庸置疑,可以大量的提高我们的效率。
    不过更多的mybatis的使用,可以参考mybatis的 官方文档

    妈耶,第一次写这么多的字,纪念一下!!

  • 相关阅读:
    团队作业第五次——Alpha冲刺
    Alpha冲刺——总结
    冲刺随笔
    冲刺随笔——Day_Nine
    冲刺随笔——Day_Eight
    冲刺随笔——Day_Seven
    冲刺随笔——Day_Three
    团队作业第五次——Alpha冲刺
    第06组 Alpha冲刺(1/6)
    第06组 团队Git现场编程实战
  • 原文地址:https://www.cnblogs.com/xiaohuiduan/p/9867669.html
Copyright © 2011-2022 走看看