05-Mybatis的动态sql

Posted on 2021-03-09 00:29  萌栈师  阅读(92)  评论(0)    收藏  举报

动态sql

​ 根据条件的不同, SQL 语句也会随之动态的改变. MyBatis 中,提供了一组标签用于实现动态 SQL,基于上一节的绑定接口实现CRUD。

一、if 条件判断

​ 用于进行条件判断, test 属性用于指定判断条件. 为了拼接条件, 在 SQL 语句后强行添加 1=1 的恒成立条件.(只要有一个条件成立就会拼接到sql语句后)

  • 注:不传入参数,即查询所有
<select id="selUser" resultType="Users">
    select * from users where 1=1
    <if test="uid!=0">
        and uid = #{uid}
    </if>
    <if test="username!=null and username!=''">
        and username = #{username}
    </if>
    <if test="password!=null and password!=''">
        and password = #{password}
    </if>
    <if test="city!=null and city!=''">
        and city = #{city}
    </if>
</select>

接口:

public List<Users> selUser(Users users);

运行代码:

/**
* 通过传入User对象,动态比对数据库,获取值
*/
@Test
public void selUser(){
    Users u = new Users();
    //u.setUid(14);
    //u.setUsername("张学友");
    u.setCity("香港");
    List<Users> users = mapper.selUser(u);
    System.out.println(users);
    sqlSession.close();
}

二、set 用于update更新语句

a) 满足条件时, 会自动添加 set 关键字

b) 会去除 set 子句中多余的逗号(最后一个条件可不写' , ')

c) 不满足条件时, 不会生成 set 关键字

例:update users set username=?,password=? where uid = 10;

<update id="updateUser">
    update users
    <set>
        <if test="username!=null and username!=''">
            username = #{username},
        </if>
        <if test="password!=null and password!=''">
            password = #{password},
        </if>
        <if test="city!=null and city!=''">
            city = #{city}
        </if>
    </set>
    where uid = #{uid}
</update>

接口:

public int updateUser(Users users);

运行代码:

@Test
public void updateUser(){
    Users users = new Users();
    users.setUsername("张三");
    users.setPassword("121212");
    users.setUid(10);
    int i = mapper.updateUser(users);
    System.out.println(i);
    sqlSession.commit();
    sqlSession.close();
}

三、where 增加查询条件

​ 用于管理 where 子句. 有如下功能:

a) 如果没有条件, 不会生成 where 关键字

b) 如果有条件, 会自动添加 where 关键字

c) 如果条件中有 ‘and’, 自动去除之,但不会自动加

  • 注:与(一)不同的是,不需要将where条件写为1=1
  • 不传入参数,即查询所有

例:select * from users WHERE username = ? and password= ?;

<select id="selUser2" resultType="Users">
    select * from users
    <where>
        <if test="uid!=0">
            and uid = #{uid}
        </if>
        <if test="username!=null and username!=''">
            and username = #{username}
        </if>
        <if test="password!=null and password!=''">
            and password = #{password}
        </if>
        <if test="city!=null and city!=''">
            and city = #{city}
        </if>
    </where>
</select>

接口:

public List<Users> selUser2(Users users);

运行代码:

@Test
public void selUser2(){
    Users u = new Users();
    u.setUsername("王二");
    u.setPassword("123123");
    List<Users> users = mapper.selUser2(u);
    System.out.println(users);
    sqlSession.close();
}

四、choose...when...otherwise(了解)

单条件查询(只取其一)

​ 这是一套标签, 功能类似于 if..elseif...elseif...else

  • 注:when中取其中的一个,不会追加多个条件,如果都不满足则找otherwise中的条件查询

  • 在when中,依次筛查条件,只要前面有条件满足,就不继续往后筛查

<select id="selByWhen" resultType="Users">
    select * from users
    <where>
        <choose>
            <when test="uid!=0">
                uid = #{uid}
            </when>
            <when test="username!=null and username!=''">
                username = #{username}
            </when>
            <when test="password!=null and password!=''">
                password = #{password}
            </when>
            <otherwise>
                city = #{city}
            </otherwise>
        </choose>
    </where>
</select>

接口:

public List<Users> selByWhen(Users users);

运行代码:

@Test
public void selByWhen(){
    Users u = new Users();
    u.setUsername("李四");
    u.setPassword("123");
    List<Users> users = mapper.selByWhen(u);
    System.out.println(users);
    sqlSession.close();
}
  • 上面在查询中加入了多个条件,程序按顺序筛查,username有值,且满足if条件判断,则不会去筛查password项,最终根据username进行查询

五、bind 模糊查询---相当于like

用于对数据进行再加工, 进行模糊查询

例:查询城市名包含‘京’的用户:select * from users where city like ‘%京%’;

方式一:使用bind,value中做字符串拼接:'%'+city+'%'

<select id="selLike" resultType="Users">
    <bind name="c" value="'%'+city+'%'"/>
    select * from users where city like #{c}
</select>

方式二:使用sql语法中的concat做拼接,concat("%",city,"%")

<select id="selLike" resultType="Users">
    select * from users where city like concat("%",#{city},"%")
</select>
  • 接口及运行代码:

接口:

public List<Users> selLike(Users users);

运行代码:

@Test
public void selLike(){
    Users u = new Users();
    u.setCity("京");
    List<Users> users = mapper.selLike(u);
    System.out.println(users);
    sqlSession.close();
}

六、foreach 范围查询

*在一个范围中查询* 用于在 SQL 语句中遍历集合参数, 在 in 查询中使用

a) collection: 待遍历的集合 (与参数名无关)

  • 如果传入的参数是List类型,collection属性值为list
  • 如果传入的参数是array数组,collection属性值为array
  • 如果传入的参数是Map类型,collection属性值就是传入的List或array对象在自己封装的map里面的key.

b) open: 设置开始符号

c) separator: 项目分隔符

d) close: 设置结束符号

e) item: 迭代变量

f) index:在list和数组中,index是元素的序号,在map中,index是元素的key,该参数可选。

  • 以List为例:select * from users where uid in (14,16,18);
<select id="selIn" resultType="Users">
    select * from users where uid in
    <foreach collection="list" open="(" separator="," close=")" item="i">
        #{i}
    </foreach>
</select>

接口:

public List<Users> selIn(List<Integer> list);

运行代码:

@Test
public void selIn(){
    List<Integer> list = new ArrayList<>();
    list.add(14);
    list.add(16);
    list.add(18);
    List<Users> users = mapper.selIn(list);
    System.out.println(users);
    sqlSession.close();
}

七、sql+include 动态选择要查询的具体列

用于提取 SQL 语句, 用于引用 SQL 语句

<sql id="aa">
    username,password
</sql>
<sql id="bb">
    city
</sql>
<select id="selColumns" resultType="Users">
    select
    <include refid="bb"></include>
    from users where uid = #{uid}
</select>

接口:

public Users selColumns(Users users);

运行代码:

@Test
public void selColumns(){
    Users u = new Users();
    u.setUid(9);
    Users users = mapper.selColumns(u);
    System.out.println(users);
    sqlSession.close();
}

博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3