前言
动态 SQL 是 MyBatis 的强大特性之一。如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL,可以彻底摆脱这种痛苦。
使用动态 SQL 并非一件易事,但借助可用于任何 SQL 映射语句中的强大的动态 SQL 语言,MyBatis 显著地提升了这一特性的易用性。借助功能强大的基于 OGNL 的表达式,MyBatis 3 替换了之前的大部分元素,大大精简了元素种类,现在要学习的元素种类比原来的一半还要少。
动态sql的元素
首先,数据库数据如图
where
对于查询条件个数不确定的情况,可使用<where>元素
<where>元素会进行判断,如果它包含的标签中有返回值的话,它就插入一个 ‘where’。
此外,如果标签返回的内容是以 AND 或 OR 开头,它会剔除掉 AND 或 OR。
if
if标签可以对传入的条件进行判断 ,默认查找adminid为1的学生
<select id="queryStudents2" parameterType="Student" resultMap="studentMap3">
select * from student
where adminid=1
<if test="num!=null">
and num=#{num}
</if>
<if test="name!=null">
and name=#{name}
</if>
<if test="gender!=null">
and gender=#{gender}
</if>
</select>
只限制查找条件为性别为男:
@Test
public void queryStudents2(){
StudentDao studentDao=sqlSession.getMapper(StudentDao.class);
Student student=new Student();
student.setGender("男");
List<Student> students = studentDao.queryStudents2(student);
sqlSession.close();
}
日志输出
加上学号的限制条件
@Test
public void queryStudents2(){
StudentDao studentDao=sqlSession.getMapper(StudentDao.class);
Student student=new Student();
student.setGender("男");
student.setNum(101);
List<Student> students = studentDao.queryStudents2(student);
sqlSession.close();
}
日志输出
choose (when, otherwise)
若有多个when满足条件,则只执行第一个条件
<select id="queryStudent" resultMap="studentMap3" parameterType="Student">
select * from student
<where>
<choose>
<when test="name!=null">
and name=#{name}
</when>
<when test="id!=null">
and id=#{id}
</when>
<otherwise>
name='张三'
</otherwise>
</choose>
</where>
</select>
测试
/*查询*/
@Test
public void query(){
StudentDao studentDao=sqlSession.getMapper(StudentDao.class);
Student student=new Student();
student.setName("王五");
student.setId(1);
studentDao.queryStudent(student);
sqlSession.commit();
sqlSession.close();
}
结果
在同时限定name和id的情况下,mybatis默认会匹配第一个条件即name
若既没有指定name和id,则根据<otherwise>里的条件进行匹配
trim (where, set)
可以用<trim>来代替<where>和<set>
<update id="update" parameterType="Student">
update student
<trim prefix="set" suffixOverrides="where">
<if test="num!=null">
num=#{num}
</if>
<if test="name!=null">
name=#{name}
</if>
<if test="gender!=null">
gender=#{gender}
</if>
</trim>
where id=#{id}
</update>
foreach
使用数组批量删除
<delete id="deleteStudents" parameterType="list">
delete from student where id in
/*可以在元素体内使用的集合项(item)和索引(index)变量*/
<foreach collection="list" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</delete>
使用list批量删除
<delete id="deleteStudents" parameterType="list">
delete from student where id in
/*可以在元素体内使用的集合项(item)和索引(index)变量*/
<foreach collection="list" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</delete>
set
<update id="update" parameterType="Student">
update student
<set>
<if test="num!=null">
num=#{num}
</if>
<if test="name!=null">
name=#{name}
</if>
<if test="gender!=null">
gender=#{gender}
</if>
</set>
where id=#{id}
</update>
测试代码,将id为2的学生性别修改为女
/*修改*/
@Test
public void update(){
StudentDao studentDao=sqlSession.getMapper(StudentDao.class);
Student student=new Student();
student.setGender("女");
student.setId(2);
studentDao.update(student);
sqlSession.commit();
sqlSession.close();
}
结果