3.Where 条件
有时候,所有的查询条件应该是可选的。在需要使用至少一种查询条件的情况下,可以直接使用WHERE子句。
如果有多个条件,我们需要在条件中添加AND或OR。MyBatis提供了<where>元素支持这种类型的动态SQL语句。
例如,在查询课程界面,假设所有的查询条件是可选的。
注意,<where>元素只有在其内部标签有返回内容时才会在动态语句上插入WHERE条件语句。
并且,如果WHERE子句以AND或者OR打头,则打头的AND或OR将会被移除。
映射文件:
<select parameterType="map" resultMap="CourseResult">
SELECT * FROM COURSES
<where>
<if test="tutorId != null ">
TUTOR_ID= #{tutorId}
</if>
<if test="courseName != null">
AND name like #{courseName}
</if>
<if test="startDate != null">
AND start_date >= #{startDate}
</if>
</where>
</select>
测试方法:
@Test
public void test_searchCourses3(){
SqlSession sqlSession = null;
try {
sqlSession = MyBatisSqlSessionFactory.openSession();
DynamicSqlMapper mapper = sqlSession.getMapper(DynamicSqlMapper.class);
Map<String,Object> map = new HashMap<String,Object>();
//map.put("tutorId", 1);
//map.put("courseName", "JavaSE");
//map.put("startDate", LocalDate.of(2019, 1, 10));
List<Course> courses = mapper.searchCourses(map);
courses.forEach(System.out::println);
} catch (Exception e) {
e.printStackTrace();
}
}
4.<trim>条件
<trim>元素和<where>元素类似,但是<trim>提供了添加 前缀/后缀 或者 移除 前缀/后缀 的功能。
映射文件:
<select parameterType="map" resultMap="CourseResult">
SELECT * FROM COURSES
<trim prefix="WHERE" suffixOverrides="and">
<if test=" tutorId != null ">
TUTOR_ID = #{tutorId} and
</if>
<if test="courseName != null">
name like #{courseName} and
</if>
</trim>
</select>
prefix表示有一个if成立则插入where语句,没有if成立,就会去掉where直接查询
suffix表示后缀,和prefix相反
suffixOverrides="and"表示如果最后生成的sql语句多一个and,则自动去掉.
prefixOverrides的意思是处理前缀,和suffixOverrides相反
测试方法:
@Test
public void test_searchCourses4(){
SqlSession sqlSession = null;
try {
sqlSession = MyBatisSqlSessionFactory.openSession();
DynamicSqlMapper mapper = sqlSession.getMapper(DynamicSqlMapper.class);
Map<String,Object> map = new HashMap<String,Object>();
// map.put("tutorId", 1);
// map.put("courseName", "JavaSE");
List<Course> courses = mapper.searchCourses(map);
courses.forEach(System.out::println);
} catch (Exception e) {
e.printStackTrace();
}
}
5.foreach 循环
另外一个强大的动态SQL语句构造标签是<foreach>。它可以迭代遍历一个数组或者列表,构造AND/OR条件或一个IN子句。
假设查询tutor_id为 1,3,6的讲师所教授的课程,我们可以传递一个tutor_id组成的列表给映射语句,然后通过<foreach>遍历此列表构造动态SQL。
映射文件:
<select parameterType="map" resultMap="CourseResult">
SELECT * FROM COURSES
<if test="tutorIds != null">
<where>
<!-- 在这里的 tutorId指的是集合中存入准备查询的tutor_id-->
<foreach item="tutorId" collection="tutorIds">
OR tutor_id = #{tutorId}
</foreach>
</where>
</if>
</select>
映射接口:
public interface DynamicSqlMapper{
List<Course> searchCoursesByTutors(Map<String,Object> map);
}
测试方法:
@Test
public void test_searchCoursesByTutors(){
SqlSession sqlSession = null;
try {
sqlSession = MyBatisSqlSessionFactory.openSession();
DynamicSqlMapper mapper = sqlSession.getMapper(DynamicSqlMapper.class);
Map<String,Object> map = new HashMap<String,Object>();
List<Integer> tutorIds = new ArrayList<Integer>();
tutorIds.add(1);
tutorIds.add(3);
tutorIds.add(6);
map.put("tutorIds", tutorIds);
List<Course> courses = mapper.searchCoursesByTutors(map);
courses.forEach(System.out::println);
} catch (Exception e) {
e.printStackTrace();
}
}
和上面同样的功能,使用<foreach>生成IN子句:
<select parameterType="map" resultMap="CourseResult">
SELECT * FROM COURSES
<if test="tutorIds != null">
<where>
tutor_id IN
<foreach item="tempValue" collection="tutorIds" open="(" separator="," close=")">
#{tempValue}
</foreach>
</where>
</if>
</select>
测试方法保持不变。
6.set 条件,专用于UPDATE更新操作
<set>元素和<where>元素类似,但是set元素只是针对update更新语句使用的。