在上一篇的:Mybatis 操作数据库的基本 CRUD 以及查询操作详析_@糊糊涂涂的博客-CSDN博客中介绍了Mybatis使用固定SQL语句操作数据,本篇介绍 Mybatis 一个强大的特性:动态SQL。
那当我们要执行的业务逻辑有很多,比如给成绩表中插入一行数据,对应学生的 “性别” 字段是非必须参数时,使用动态SQL就不用写两种插入语句(传与不传性别);
另外,当执行查询逻辑时,条件中的参数个数也是不确定的。
以上类似传入参数不确定的情况,都可以使用动态SQL来解决。
下面假设要给 student 表插入一行数据,学生的 sex 字段对应的实体类中 sex 属性值为null,借助
Maper 接口:
@Mapper
public interface StudentMapper {
// 新增学生信息
int addStu(Student student);
}
插入语句:
insert into student (uid, name
,sex
,score
) values (#{uid}, #{name}
,#{sex}
,#{score})
测试方法:
@SpringBootTest
class StudentMapperTest {
@Autowired
private StudentMapper studentMapper;
@Transactional
@Test
void addStu() {
Student student = new Student();
student.setUid(1);
student.setName("张三");
student.setScore(98);
// 传入的实体对象中不包含 sex
int result = studentMapper.addStu(student);
System.out.println("插入成功:" + result);
}
}
!!!使用时要注意区分属性和字段:
test 里要判断的是“属性” —— 来自实体类对象;
其他的是字段 —— 和数据库对应;
当SQL语句中有很多个非必传参数时,一旦只传其中个别参数,就会导致残留逗号或括号等情况,导致SQL语句出现错误;
标签的四个参数: 可根据场景添加
- prefix:表示整个语句块,以prefix的值作为前缀
- suffix:表示整个语句块,以suffix的值作为后缀
- prefixOverrides:表示整个语句块要去除掉的前缀
- suffixOverrides:表示整个语句块要去除掉的后缀
下面演示:插入一条学生信息,但参数只传学生名,就会导致字段后面多出一个逗号,同时如果不穿参数,又会多出一对括号,借助 trim 来修改:
Mapper 接口:
@Mapper
public interface StudentMapper {
// 只插入学生姓名
int addStuOnlyName(Student student);
}
SQL 语句:
insert into student
uid,
name,
sex,
score
values
#{uid},
#{name},
#{sex},
#{score}
单元测试:
@Test
void addStuOnlyName() {
Student student = new Student();
student.setName("李四");
int result = studentMapper.addStuOnlyName(student);
System.out.println("插入成功:" + result);
}
直接借助示例演示:根据学生 uid 或 学生名 来查询一条学生信息,这里的两个查询条件都是非必传的。
① 如果查询时只给了其中一个条件,那么 where 后面连接时的 "and" 就会被多出来;
② 如果两个条件都不穿,那么 "where" 就会被多出来;
针对第一种情况:可以使用
针对第二种情况:解决办法很多种:
update student
uid = #{uid},
name = #{name},
sex = #{sex},
score = #{score}
where uid = #{uid}
- collection:绑定方法参数中的集合,如 List,Set,Map或数组对象
- item:遍历时的每⼀个对象
- open:语句块开头的字符串
- close:语句块结束的字符串
- separator:每次遍历的对象之间间隔的字符串
// 根据 uid 批量删除
int deleteByUids(List uidList);
delete from student
where uid in
#{uid}