Skip to content

动态SQL ​

根据前端传入的条件不同,执行不同结构的查询条件, 需要动态组织SQL语句,比如在多个条件查询中,有可能不需要将所有的查询条件都有值去查询,比如无值的这个字段就不需要增加查询条件了,在这里我们就需要使用到动态查询了。

我们可以通过两种方式实现动态sql的生成, 分别是:

  1. xml方式
  2. mybatis-plus方式

动态条件查询 ​

演示代码的需求:根据前端传入的User对象中不为空的属性进行查询。

xml方式 ​

xml中动态sql的前置知识

动态SQL标签:

  • <where>:只会在有成立的if条件时,才会插入WHERE子句,而且还会自动去除第一个条件前面多余的and/or
  • <if>:条件判断,在test属性中指定的条件成立时,才会拼接对应的SQL片段

UserMapper

java
package com.itheima.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.itheima.entity.User;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface UserMapper extends BaseMapper<User> {
    //根据传入的User对象中不为空的属性进行查询
    List<User> selectByUser(User user);
}

UserMapper.xml

xml
<!-- 根据传入的User对象中不为空的属性进行查询 支持动态SQL-->
<!--
    <if>:条件判断,在test属性中指定的条件成立时,才会拼接对应的SQL片段
    <where>:只会在有成立的if条件时,才会插入WHERE子句,而且还会自动去除第一个条件前面多余的and/or。
-->
<select id="selectByUser" resultType="com.itheima.entity.User">
    select * from user
    <where>
        <if test="id != null">
            id = #{id}
        </if>
        <if test="username != null and username != ''">
            and username like concat( '%',#{username} ,'%')
        </if>
        <if test="password != null and password != ''">
            and password = #{password}
        </if>
        <if test="name != null and name != ''">
            and name like concat ('%' , #{name}, '%')
        </if>
        <if test="age != null">
            and age = #{age}
        </if>
    </where>
</select>

测试类

java
/**
 * 测试根据传入的User对象中不为空的属性进行查询方法
 */
@Test
public void testSelectByUser() {
    User user = new User();
    user.setUsername("zhangsan");
    //user.setName("张三");
    user.setAge(18);
    List<User> list = userMapper.selectByUser(user);
    System.out.println(list);
}

Mybatisplus的方式 ​

如果我们只是**对单表进行动态条件查询**, 其实mybatis-plus也是可以完成的, mybatis-plus的所有的构建条件的方法都重载了可以加入判断后再拼接条件的能力, 完成sql条件的动态拼接, 例如以上的效果我们可以这样实现:

java
public class UserMapperTest {
    @Autowired
    private UserMapper userMapper;
    @Test
    public void testSelectByCondition(){
    
        User user = new User();
        user.setUsername("zhangsan");
        //user.setName("张三");
        user.setAge(18);
        
        LambdaQueryWrapper<Student> lqw = new LambdaQueryWrapper<>();
        lqw
        .eq(user.getId()!=null , User::getId, user.getId())
        .like(StringUtils.isNotBlank(user.getUsername()), User::getUsername, user.getUsername())
        .eq(StringUtils.isNotBlank(user.getPasword()) , User::getPassword, user.getPassword())
        .like(StringUtils.isNotBlank(user.getName()) , User::getName, user.getName())
        .eq(user.getAge()!=null, User::getAge, user.getAge());
    
        List<User> users= userMapper.selectList(lqw);
        for (User u: users) {
            System.out.println(u);
        }
    
    }
 }

知识点补充

StringUtils的使用

我们经常会判断字符串是否为null或者""或者" "去除空格是否为""等这种无效的情况, 我们可以采用StringUtils工具类帮我们简化对应的判断, 例如以上的代码可以简化成如下内容:

(注: 很多框架都有StringUtils, 此时这边采用的mp框架的StringUtils , 其实hool工具包中其实也有类似的工具, 都能解决该问题)

条件批量删除 ​

需求:根据前端出入的ID集合批量删除

sql
delete from user where id in (1,3,10);

知识点

**<foreach>**标签:xml中提供的用于对集合 / 数组进行遍历,使用的方式如下:

xml
<foreach collection="要遍历的集合/数组" item="每次遍历的元素变量名" open="拼接的开头字符" close="拼接的结尾字符" separator="元素之间的分隔符">
    #{item}  <!-- 使用遍历出来的值 -->
</foreach>

UserMapper

java
package com.itheima.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.itheima.entity.User;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface UserMapper extends BaseMapper<User> {
    //根据前端出入的ID集合批量删除
    int deleteBatchIds(List<Integer> idList);
}

UserMapper.xml

java
<!--
    foreach:
        collection="要遍历的集合/数组"
        item="每次遍历的元素变量名"
        open="拼接的开头字符"
        close="拼接的结尾字符"
        separator="元素之间的分隔符"
-->
<delete id="deleteBatchIds">
    delete from user where id in
    <foreach collection="idList" item="item" separator="," open="(" close=")">
        #{item}
    </foreach>
</delete>

测试类

java
/**
 * 测试根据前端传入的ID集合批量删除方法
 */
@Test
public void testDeleteBatchIds() {
    List<Integer> idList = List.of(1, 2, 3, 4);
    int result = userMapper.deleteBatchIds(idList);
    System.out.println("删除结果: " + result);
}