上一节讲到了动态sql中的if条件和:choose,when 和otherwise 条件。这一节讲述更多的动态sql条件。
一、where条件:where条件具有以下两个功能:
1,自动加上where;
2,如果where 子句以and 或者or 开头,则自动删除第一个and 或者or;
上一节在讲if条件的时候,sql映射器中为了防止传入的map为空,在where后面加上了1=1这个常值条件,这样处理总给人一种不严谨的感觉。现在使用where条件就可以完全解决这个问题了。
在StudentMapper中添加接口:
public List<Student> searchStudents3(Map<String,Object> map);
sql映射器中实现这个方法:
<select id="searchStudents3" parameterType="Map" resultMap="StudentResult">
select * from t_student
<where>
<if test="name!=null">
and name like #{name}
</if>
<if test="age!=null">
and age=#{age}
</if>
<if test="gradeId!=null">
and gradeId = #{gradeId}
</if>
</where>
</select>
这里使用了where条件。where条件会在有<where>的地方自动加上where,另外如果where子句以and或者or开头的话,会自动删除第一个and或者or。如果where子句为空,也不会添加where了。
添加测试方法:
@Test
public void testSearchStudents3() {
logger.info("查询学生(带条件)");
Map<String,Object> map = new HashMap<String,Object>();
map.put("name", "%李%");
List<Student> studentList = studentMapper.searchStudents3(map);
for(Student s:studentList){
System.out.println(s);
}
}
运行这个测试方法,执行where条件后,拼接的sql语句为:select * from t_student where name like %李%(在拼接sql语句的时候自动加上where,如果where子句以and或or开头,则删除第一个and或者or)。运行这个测试方法,能够成功查询出想要的学生信息。
二、trim 条件
功能和where 元素类似,提供了前缀,后缀功能,更加灵活。看实例:
1.添加接口方法:
public List<Student> searchStudents4(Map<String,Object> map);
2.使用trim条件实现该方法:
<select id="searchStudents4" parameterType="Map" resultMap="StudentResult">
select * from t_student
<trim prefix="where" prefixOverrides="and|or">
<if test="name!=null">
and name like #{name}
</if>
<if test="age!=null">
and age=#{age}
</if>
<if test="gradeId!=null">
and gradeId = #{gradeId}
</if>
</trim>
</select>
这里使用trim条件,prefix属性指定前缀,这里是where,也就是拼写sql语句的时候,在拼接trim里面的语句之前加上where;prefixOverrides表示前缀覆盖,它的值是and|or,意思是如果trim条件里面的语句以and或者or开头,则删除这个and或者or。可以看到这样的话其功能和where条件非常的像。其灵活的地方是还可以添加后缀(suffix属性以及后缀覆盖suffixOverrides属性,不过添加后缀使用的非常少)。
3.添加测试方法:
@Test
public void testSearchStudents4() {
logger.info("查询学生(带条件)");
Map<String,Object> map = new HashMap<String,Object>();
//map.put("gradeId", 2);
map.put("name", "%李%");
//map.put("age", 11);
List<Student> studentList = studentMapper.searchStudents4(map);
for(Student s:studentList){
System.out.println(s);
}
}
运行这个测试方法查到相应的学生信息。
三、foreach 循环
假设有100多个班级,我们要查询其中1~5班的所有学生。写成sql语句为:select * from t_student where gradeId in (1,2,3,4,5)。当查询的班级变化时,也要重新手动的写查询语句。现在使用foreach循环能够动态的实现 班级的变化。
1.添加接口方法:
public List<Student> searchStudents5(Map<String,Object> map);
2.实现该接口方法:
<select id="searchStudents5" parameterType="Map" resultMap="StudentResult">
select * from t_student
<if test="gradeIds != null">
<where>
gradeId in
<foreach item="gradeId" collection="gradeIds" open="(" separator="," close=")">
#{gradeId}
</foreach>
</where>
</if>
</select>
这里使用了foreach循环。其中
<foreach item="gradeId" collection="gradeIds" open="(" separator="," close=")">
#{gradeId}
</foreach>
会把传入的班级名字以逗号隔开,并放在()中。open属性值为“(”,close值为“)”:表示将foreach里面的内容放在()中;separator属性值为“,”:表示foreach里面的内容使用逗号隔开。collection属性值为gradeIds,表示对于集合gradeIds中的所有元素,item属性值为gradeId表示从gradeIds中取出一个元素赋值给gradeId。
3.添加测试方法:
@Test
public void testSearchStudents5() {
logger.info("查询学生(带条件)");
Map<String,Object> map = new HashMap<String,Object>();
List<Integer> gradeIds = new ArrayList<Integer>();
gradeIds.add(1);
gradeIds.add(2);
map.put("gradeIds", gradeIds);
List<Student> studentList = studentMapper.searchStudents5(map);
for(Student s:studentList){
System.out.println(s);
}
}
这里gradeIds中的值为1和2,最终拼接成的sql语句为:select * from t_student where gradeId in (1,2)。运行这个测试方法,能够得到想要的学生信息。
四、set 条件:set条件和where都是使用的最多的条件,set条件常用在更新数据库中。set条件具有以下特性:
1,自动加上set;
2,自动剔除最后一个逗号“,”;
之前更新数据库中的信息时,是把一条数据的所有项都进行更新,即使有的项并没有更新。使用set语句能够只更新变化的项。
3.StudentMapper中添加方法:
public int updateStudent(Student student);
4.使用set条件实现这个方法:
<update id="updateStudent" parameterType="Student">
update t_student
<set>
<if test="name!=null">
name=#{name},
</if>
<if test="age!=null">
age=#{age},
</if>
</set>
where id=#{id}
</update>
在<set>的位置会自动添加set,另外还会去掉set语句中最末尾的逗号。
5.添加测试方法:
@Test
public void testUpdateStudent(){
logger.info("更新学生");
Student student = new Student();
student.setId(1);
student.setName("张三3");
student.setAge(13);
studentMapper.updateStudent(student);
sqlSession.commit();
}
这里把id为1的学生的姓名改成张三3,年龄改成13岁。拼接成的sql语句为:update t_student set name=张三3,age=13 where id=1;
运行这个测试方法,数据库中发生了相关的变化。