学科分类
目录
SSM框架

<choose>、<when>、<otherwise>元素

在使用<if>元素时,只要test属性中的表达式为true,就会执行元素中的条件语句,但是在实际应用中,有时只需要从多个选项中选择一个去执行。

例如下面的场景:

“当客户名称不为空,则只根据客户名称进行客户筛选;

当客户名称为空,而客户职业不为空,则只根据客户职业进行客户筛选。

当客户名称和客户职业都为空,则要求查询出所有电话不为空的客户信息。”

此种情况下,使用<if>元素进行处理是非常不合适的。如果使用的是Java语言,这种情况显然更适合使用switch…case…default语句来处理。那么在MyBatis中有没有类似的语句呢?答案是肯定的。针对上面情况,MyBatis中可以使用<choose>、<when>、<otherwise>元素进行处理。下面让我们看看如何使用<choose>、<when>、<otherwise>元素组合去实现上面的情况。

(1)在映射文件CustomerMapper.xml中,使用<choose>、<when>、<otherwise>元素执行上述情况的动态SQL代码如下所示。

<!--<choose>(<when>、<otherwise>)元素使用 -->
<select id="findCustomerByNameOrJobs" 
        parameterType="com.itheima.po.Customer"
        resultType="com.itheima.po.Customer">
    select * from t_customer where 1=1
    <choose>
        <when test="username !=null and username !=''">
            and username like concat('%',#{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中,编写测试方法findCustomerByNameOrJobsTest(),其代码如下所示。

/**
 * 根据客户姓名或职业查询客户信息列表
 */
@Test
public void findCustomerByNameOrJobsTest(){
    // 通过工具类生成SqlSession对象
    SqlSession session = MybatisUtils.getSession();
    // 创建Customer对象,封装需要组合查询的条件
    Customer customer = new Customer();
    customer.setUsername("jack");
    customer.setJobs("teacher");
    // 执行SqlSession的查询方法,返回结果集
    List<Customer> customers = session.selectList("com.itheima.mapper" 
            + ".CustomerMapper.findCustomerByNameOrJobs",customer);
    // 输出查询结果信息
    for (Customer customer2 : customers) {
        // 打印输出结果
        System.out.println(customer2);
    }
    // 关闭SqlSession
    session.close();
}

使用JUnit4执行findCustomerByNameOrJobsTest()方法后,控制台的输出结果如图1所示。

图1 运行结果

从图1可以看出,虽然同时传入了姓名和职业两个查询条件,但MyBatis所生成的SQL只是动态组装了客户姓名进行条件查询。

如果将上述代码中“customer.setUsername("jack");”删除或者注释掉,然后再次执行findCustomerByNameOrJobsTest()方法时,控制台的输出结果如图2所示。

图2 运行结果

从图2可以看出,MyBatis生成的SQL组装了客户职业进行条件查询,同样查询出了客户信息。

如果将设置客户姓名和职业参数值的两行代码都注释(即客户姓名和职业都为空),那么程序的执行结果如图3所示。

图3 运行结果

从图3可以看出,当姓名和职业参数都为空时,MyBatis的SQL组装了<otherwise>元素中的SQL片段进行条件查询。

点击此处
隐藏目录