<choose>
、<when>
和<otherwise>
元素
在使用<if>
元素时,只要test属性中的表达式为true,就会执行元素中的条件语句,但是在实际应用中,有时只需要从多个选项中选择一个执行。例如,若用户姓名不为空,则只根据用户姓名进行筛选;若用户姓名为空,而用户职业不为空,则只根据用户职业进行筛选;若用户姓名和用户职业都为空,则要求查询出所有电话不为空的用户信息。
此种情况下,使用<if>
元素进行处理是非常不合适的,可以使用<choose>
、<when>
、<otherwise>
元素进行处理,类似于在Java语言中使用switch…case…default语句。
【示例】使用<choose>
、<when>
、<otherwise>
元素组合实现上面的情况。
(1)在映射文件UserMapper.xml中,使用<choose>
、<when>
、<otherwise>
元素执行上述情况的动态SQL代码如下所示。
<!--<choose>、<when>和<otherwise>元素使用--><select id="findUserByNameOrJobs" parameterType="com.ssm.po.User" resultType="com.ssm.po.User">select * from t_user where 1=1<choose><when test="username !=null and username != ''">and username like connect ('%', #{username}, '%')</when><when test="jobs !=null and jobs != ''">and jobs = #{jobs}</when><otherwise>and phone is not null</otherwise></choose></select>
在上述代码中,使用了<choose>
元素进行SQL拼接,若第一个<when>元
素中的条件为真,则只动态组装第一个<when>
元素内的SQL片段;否则继续向下判断第二个<when>
元素中的条件是否为真,以此类推;若前面所有when元素中的条件都不为真,则只组装<otherwise>
元素内的SQL片段。
(2)在测试类MybatisTest中,编写测试方法findUserByNameOrJobsTest(),其代码如下所示。
/**根据用户姓名和职业组合条件查询用户信息列表*/@Testpublic void findUserByNameOrJobsTest() throws Exception {//通过工具类生成SqlSession对象SqlSession sqlSession = MybatisUtil.getSession();//创建User对象,封装需要组合查询的条件User user = new User();user.setUsername("zhangsan");user.setJobs("teacher");//执行SqlSession的查询办法,返回结果集List<User> users =sqlSession.selectList("com.ssm.mapper.UserMapper.findUserByNameOrJobs",user);//输出查询结果for (User u :users) {System.out.println(u.toString());}sqlSession.close();}
执行上述方法后,虽然同时传入了姓名和职业两个查询条件,但MyBatis所生成的SQL是动态组装用户姓名进行条件查询的。如果将上述代码中的“user.setUsername("zhangsan");
”删除或者注释掉,然后再次执行,这时MyBatis生成的SQL组装用户职业进行条件查询,同样会查询出用户信息。如果将设置客户姓名和职业参数值的两行代码都注释掉,那么程序的执行结果如图所示,MyBatis的SQL组装<otherwise>
元素中的SQL片段进行条件查询。