2023.11.27 关于 MyBatis 动态 SQL 的使用

目录

引言

if 标签 

trim 标签 

where 标签 

set 标签 

foreach 标签 


引言

  • 动态 sql 是 MyBatis 的强大特性之一
  • 允许你根据输入的参数动态地构建 sql 语句
  • 从而在运行时根据不同的条件生成不同的 sql

核心思想

  • 基于提供的数据和条件,能够修改、增加、删除 sql 语句的部分内容
  • 这为编写更通用、可重用的 sql 提供了极大的灵活性

  • 以下我们介绍 5 个常用的动态 sql 标签

if 标签 

实例理解

  • 此处我们想要实现 根据 name 和 age 字段来筛选用户信息 功能

创建数据库

  • 在数据库中创建一个如下图所示的 user 表,并插入几条用户数据
  • 注意这里的 state 状态
  • 值为 1 表示该用户可正常登录
  • 值为 0 表示该用户异常,无法登录

2023.11.27 关于 MyBatis 动态 SQL 的使用_第1张图片


实现 UserMapper 接口

  • 此处我们实现一个 selectUser 方法
import com.example.demo.entity.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

import java.util.List;

//添加 @Mapper 注解 代表该接口会伴随这 项目的启动而注入到容器中
@Mapper
public interface UserMapper {

//    根据 name 和 age 字段来筛选用户信息
    List selectUser(@Param("user_name") String name,
                          @Param("user_age") Integer age);
}

实现 UserMapper XML 文件

  • 在与接口相对应的 XML 文件中
  • 添加上与 selectUser 方法 相对应的 sql语句




    



分析功能 与 select 语句

  • 根据 name 和 age 字段筛选用户信息    存在四种情况

情况一:

  • name 和 age 均不为空,其所对应的 sql 语句为:
select * from user where name = #{user_name} and age = #{user_age}

情况二:

  • name 和 age 均为空,其所对应的 sql 语句为:
select * from user

情况三:

  • name 为空, age 不为空,其所对应的 sql 语句为:
select * from user where age = #{user_age}

情况四:

  • name 不为空, age 为空,其所对应的 sql 语句为:
select * from user where name = #{user_name}

分析 XML 中的 select 语句 

  • 加上 if 标签后,该 sql 也将存在四种情况,与上述分析的四种情况相对应

2023.11.27 关于 MyBatis 动态 SQL 的使用_第2张图片

注意:

  • 理解此处加上的 绿框部分,即 '1=1'
  • 如果删除绿框部分,那么我们再观察下图

2023.11.27 关于 MyBatis 动态 SQL 的使用_第3张图片

  • 所以 XML 中的 select 语句必须加上绿框部分,否则将会导致 sql 语法错误

创建 selectUser 的测试方法

  • 我们随意选择上述四种情况的任意一种进行传参
  • 此处我们选择仅传参 age= 20
@Test
    void selectUser() {
        List users = userMapper.selectUser(null,20);
        users.stream().forEach(System.out::println);
    }

执行测试方法

  • 测试方法成功执行

2023.11.27 关于 MyBatis 动态 SQL 的使用_第4张图片

trim 标签 

属性

  • prefix:表示整个语句块,以 prefix 的值作为前缀
  • suffix:表示整个语句块,以 suffix 的值作为后缀
  • prefixOverrides:表示整个语句块,所需要去除的多余前缀
  • suffixOverrides:表示整个语句块,所需要去除的多余后缀

实例理解

  • 下方的 select 查询语句为了保证 sql 语法的正确性,还必须得添加上 '1=1' 
  • 但是我们可以使用  标签来改写上方的 select 语句,使其可以不用添加上 '1=1'的同时保障 sql 语法的正确性
select * from user
        
            
                 name = #{user_name} and
            
            
                 age =#{user_age}
            
        

分析该 sql 语句

  • 此处经存在一种情况会 发生去除多余后缀 'and' 

2023.11.27 关于 MyBatis 动态 SQL 的使用_第5张图片


注意:

  •  标签中生成了代码那么才会添加 标签里的前缀和后缀
  • 如果  标签中未生成代码,则前缀和后缀都会省略

2023.11.27 关于 MyBatis 动态 SQL 的使用_第6张图片

where 标签 

实例理解

  • 我们同样可以使用 标签来改写上述 根据 name 和 age 字段来筛选用户信息 的 sql 语句

注意:

  • 上述实例为  标签的正确写法不能写成下述 sql 语句
  • 因为  标签会帮去除最前面的多余 'and' 关键字 ,而不会帮去除最后面的多余 'and' 关键字
  • 标签相当于

set 标签 

实例理解

  • 此处我们想实现一个 根据用户 id 修改用户各属性 功能

准备数据库

  • 在数据库中准备好一个 user 表

2023.11.27 关于 MyBatis 动态 SQL 的使用_第7张图片


 实现 UserMapper 接口

  • 此处我们实现一个 updateById 方法
import com.example.demo.entity.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

import java.util.List;

//添加 @Mapper 注解 代表该接口会伴随这 项目的启动而注入到容器中
@Mapper
public interface UserMapper {
//    根据 id 修改用户信息
    Integer updateById(User user);

}

实现 UserMapper XML 文件

  • 在与接口相对应的 XML 文件中
  • 添加上与 updateById 方法 相对应的 sql语句




    
        update user
        
            
                name = #{name},
            
            
                age = #{age},
            
            
                password = #{password},
            
            
                state = #{state}
            
        
        where id = #{id}
    



创建 updateById 的测试方法

  • 此处我们修改 用户 id = 4 用户信息
  • 修改其姓名、年龄、密码,不修改其状态
@Test
void updateById() {
    User user = new User();
    user.setId(4);
    user.setName("haoran");
    user.setAge(20);
    user.setPassword("123123");
    int result = userMapper.updateById(user);
    System.out.println("updateById 方法 :" + (result == 1 ? "修改成功" : "修改失败"));
}

执行测试方法

  • 测试方法成功执行

2023.11.27 关于 MyBatis 动态 SQL 的使用_第8张图片

  • 观察数据库中的 user 表

2023.11.27 关于 MyBatis 动态 SQL 的使用_第9张图片


注意:

  • 标签相当于

foreach 标签 

属性

  • collection:绑定方法参数中的集合,如 List、Set、Map 或数组对象
  • item:遍历时的每一个对象
  • open:语块开头的字符串
  • close:语块结束的字符串
  • separator:每次遍历之间间隔的字符串

实例理解

  • 此处想实现一个 根据多个用户 Id 来批量封禁用户 功能

 准备数据库

  • 在数据库中准备好一个 user 表

2023.11.27 关于 MyBatis 动态 SQL 的使用_第10张图片


 实现 UserMapper 接口

  • 此处我们实现一个 updateStateByIds 方法
import com.example.demo.entity.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

import java.util.List;

//添加 @Mapper 注解 代表该接口会伴随这 项目的启动而注入到容器中
@Mapper
public interface UserMapper {
//    根据多个 id 批量封禁用户
    Integer updateStateByIds(@Param("user_ids") List ids);
}

实现 UserMapper XML 文件

  • 在与接口相对应的 XML 文件中
  • 添加上与 updateStateByIds 方法 相对应的 sql语句




    
        update user set state = 0
        where id in
        
            #{item}
        
    



创建 updateStateByIds 的测试方法

  • 此处我们封禁 id = 1、4、8、9  的用户
@Test
void updateStateByIds() {
    List ids = new ArrayList<>();
    ids.add(1);
    ids.add(4);
    ids.add(8);
    ids.add(9);
    int result = userMapper.updateStateByIds(ids);
    System.out.println("updateById 方法 :" + (result > 1 ? "修改成功" : "修改失败"));
}

执行测试方法

  • 测试方法成功执行

2023.11.27 关于 MyBatis 动态 SQL 的使用_第11张图片

  • 观察数据库中的 user 表

2023.11.27 关于 MyBatis 动态 SQL 的使用_第12张图片

你可能感兴趣的:(Spring,mybatis,sql,数据库)