动态sql语句的用法

                                        动态SQL语句的简单使用

一:概念:

    根据需求,来动态的实现sql语句。

二:作用:

  根据需求,实现SQL语句的拼接。

三:使用

通过标签来使用: if, choose,  otherwise,  trim,  when,where, set, foreach等标签

注意:and,or等关系词要放进<标签>里面; where 后面一定得接 1 = 1 表示true,如果是<where>标签这就不是必要的。

1).<if>标签

  select * from user where

      <if test="username != null">
         username=#{username}
      </if> 
      <if test="username != null">
          and sex=#{sex}
      </if>
2). <where>标签
where标签可以过滤掉条件语句中的第一个andor关键字

  select * from user

     <where>

      <if test="username != null">

         username=#{username}
      </if> 
      <if test="username != null">
          and sex=#{sex}
      </if>
     </where>
3). <choose>标签,<when>标签,<otherwise>标签
我们不想用到所有的查询条件,只想选择其中的一个,查询条件有一个满足即可,使用 choose 标签可以解决此类问题,类似于 Java 的 switch 语句
 注意: 不仅仅要判非空,还得判非空串
<select id="selectUserByChoose" resultType="com.ys.po.User" parameterType="com.ys.po.User">
      select * from user
      <where>
          <choose>
              <when test="id !='' and id != null">
                  id=#{id}
              </when>
              <when test="username !='' and username != null">
                  and username=#{username}
              </when>
              <otherwise>
                  and sex=#{sex}
              </otherwise>
          </choose>
      </where>
 </select>
 

也就是说,这里我们有三个条件,id,username,sex,只能选择一个作为查询条件

    如果 id 不为空,那么查询语句为:select * from user where  id=?

    如果 id 为空,那么看username 是否为空,如果不为空,那么语句为 select * from user where  username=?;

          如果 username 为空,那么查询语句为 select * from user where sex=?

4).<forEach>标签

需求:我们需要查询 user 表中 id 分别为1,2,3的用户

sql语句:select * from user where id=1 or id=2 or id=3

     select * from user where id in (1,2,3)

 

①、建立一个 UserVo 类,里面封装一个 List<Integer> ids 的属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package com.ys.vo;
 
import java.util.List;
 
public class UserVo {
    //封装多个用户的id
    private List<Integer> ids;
 
    public List<Integer> getIds() {
        return ids;
    }
 
    public void setIds(List<Integer> ids) {
        this.ids = ids;
    }
 
}  

 

②、我们用 foreach 来改写 select * from user where id=1 or id=2 or id=3

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<select id="selectUserByListId" parameterType="com.ys.vo.UserVo" resultType="com.ys.po.User">
    select * from user
    <where>
        <!--
            collection:指定输入对象中的集合属性
            item:每次遍历生成的对象
            open:开始遍历时的拼接字符串
            close:结束时拼接的字符串
            separator:遍历对象之间需要拼接的字符串
            select * from user where 1=1 and (id=1 or id=2 or id=3)
          -->
        <foreach collection="ids" item="id" open="and (" close=")" separator="or">
            id=#{id}
        </foreach>
    </where>
</select>

  测试:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//根据id集合查询user表数据
@Test
public void testSelectUserByListId(){
    String statement = "com.ys.po.userMapper.selectUserByListId";
    UserVo uv = new UserVo();
    List<Integer> ids = new ArrayList<>();
    ids.add(1);
    ids.add(2);
    ids.add(3);
    uv.setIds(ids);
    List<User> listUser = session.selectList(statement, uv);
    for(User u : listUser){
        System.out.println(u);
    }
    session.close();
}

  

③、我们用 foreach 来改写 select * from user where 1=1 and id in (1,2,3)

<select id="selectUserByListId" parameterType="com.ys.vo.UserVo" resultType="com.ys.po.User">

        select * from user
        <where>
            <!--
                collection:指定输入对象中的集合属性,意思就是要遍历的对象名称
                item:每次遍历生成的对象
                  index:当前元素在集合里面的下标位置
                open:开始遍历时的拼接字符串
                close:结束时拼接的字符串
                separator:遍历对象之间需要拼接的字符串
                select * from user where 1=1 and id in (1,2,3)
              -->
              1 = 1
            <foreach collection="ids" item="id" open="and id in (" close=") " separator=",">
                #{id}
            </foreach>
        </where>
    </select>
 
 
5).set标签
set标签遇到逗号,会把多余的逗号去掉
多是与  if  连用
 
 update user u

        <set>
            <if test="username != null and username != ''">
                u.username = #{username},
            </if>
            <if test="sex != null and sex != ''">
                u.sex = #{sex}
            </if>
        </set>
     
 where id=#{id}

 

6).bind标签
注意:bind标签要放在sql前面,白哦是自定义一个上下文
 
<bind  name = " pattern_name "  value = "  '%' + _name + '%' "/>
<bind  name = " pattern_age"  value = "  '%' + age+ '%' "/>
select * from table 
where
name like #{pattern_name} 
and age like #{pattern_age} 
 
 
7). sql片段
有时候可能某个 sql 语句我们用的特别多,为了增加代码的重用性,简化代码,我们需要将这些代码抽取出来,然后使用时直接调用。

比如:假如我们需要经常根据用户名和性别来进行联合查询,那么我们就把这个代码抽取出来,如下:

1
2
3
4
5
6
7
8
9
<!-- 定义 sql 片段 -->
<sql id="selectUserByUserNameAndSexSQL">
    <if test="username != null and username != ''">
        AND username = #{username}
    </if>
    <if test="sex != null and sex != ''">
        AND sex = #{sex}
    </if>
</sql>

  引用 sql 片段

1
2
3
4
5
6
7
8
<select id="selectUserByUsernameAndSex" resultType="user" parameterType="com.ys.po.User">
    select * from user
    <trim prefix="where" prefixOverrides="and | or">
        <!-- 引用 sql 片段,如果refid 指定的不在本文件中,那么需要在前面加上 namespace -->
        <include refid="selectUserByUserNameAndSexSQL"></include>
        <!-- 在这里还可以引用其他的 sql 片段 -->
    </trim>
</select>

  注意:①、最好基于 单表来定义 sql 片段,提高片段的可重用性

     ②、在 sql 片段中最好不要包括 where

posted @ 2020-07-01 12:46  lanto_liang  阅读(339)  评论(0编辑  收藏  举报