MyBatis(三)MyBatis的动态SQL

动态SQL中的元素

MyBatis的动态SQL元素
元素说明
<if>判断语句,用于单条件分支判断
<choose>、(<when>、<otherwise>)相当于java中的switch...case...default语句,用于多条件分支判断
<where>、<trim>、<set>处理SQL拼装,特殊字符问题
<foreach>循环语句,常用于in语句等列举条件中
<bind>从OGNL表达式中创建一个变量,并将其绑定到上下文,常用于模糊查询的sql中

 

 

 

 

 

 

 

1.<if>元素

在使用<if>元素时,只要test属性中的表达式为true,就会执行元素中的条件语句

(1)CustomerMapper.xml

<mapper namespace="com.itcast.mapper.CustomerMapper">
     <!--<if>元素使用-->
<select id="findCustomerByNameAndJobs"
        parameterType="com.itcast.po.Customer"
        resultType="com.itcast.po.Customer"
        select * from t_customer where 1=1
        <if test="username !=null and username !=''">
           and username like concat('%',#{username},'%')
        </if>
        <if test="jobs" !=null and jobs !=''">
            and jobs=#{jobs}
        </if>
</select>
</mapper>

使用<if>元素的test属性分别对username和jobs进行了非空判断(test属性多用于条件判断语句中,用于判断真假,大部分的场景中都是进行非空判断,有时候也需要判断字符串,数字和枚举等),如果传入的查询条件非空就进行动态SQL组装

(2)测试类MyBatisTest

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

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

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

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

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

案例:

(1)在映射文件CustomerMapper.xml中

<!--<choose>(<when>、<otherwise>)元素使用-->
<select id="findCustomerByNameOrJobs"
          parameterType="com.itcast.po.Customer"
          resultType="com.itcast.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)测试

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

 

3.<where>、<trim>元素

select * from t_customer where and username like concat('%',?,'%')
    <!--<where>元素-->
<select id="findCustomerByNameAndJobs"
        parameterType="com.itcast.po.Customer"
        resultType="com.itcast.po.Customer"
        select * from t_customer 
<where>
        <if test="username !=null and username !=''">
           and username like concat('%',#{username},'%')
        </if>
        <if test="jobs" !=null and jobs !=''">
            and jobs=#{jobs}
        </if>
</where>
</select>

<where>元素会自动判断组合条件下拼装的SQL语句,只有<where>元素内的条件成立时,才会在拼接SQL中加入where关键字,否则将不会添加;即使where之后的内容有多余的"AND"或"OR",<where>元素也会自动将它们去除.

上述代码还可以修改成如下形式:

<!--<trim>元素-->
<select id="findCustomerByNameAndJobs"
        parameterType="com.itcast.po.Customer"
        resultType="com.itcast.po.Customer">
   select * from t_customer
<trim prefix="where" prefixOverrides="and">
 <if test="username !=null and username !=''">
           and username like concat('%',#{username},'%')
        </if>
        <if test="jobs" !=null and jobs !=''">
            and jobs=#{jobs}
        </if>
</trim>
</select>

<trim>元素的作用就是去除一些特殊的字符串,它的prefix属性代表的是语句的前缀(这里使用where来连接后面的SQL片段),而prefixOverrides属性代表的是需要去除的那些特殊字符串(这里定义了要去除SQL中的and)

4.<set>元素

<set>元素主要用于更新操作,主要作用是在动态包含的SQL语句前输出一个SET关键字,并将SQL语句中最后一个多余的逗号去除

案例:使用<set>元素对映射文件中更新客户信息的SQL语句进行修改

​
<!--<set>元素-->
<update id="updateCustomer"
        parameterType="com.itcast.po.Customer">
    update t_customer
<set>
        <if test="username !=null and username !=''">
           username =#{username},
        </if>
        <if test="jobs" !=null and jobs !=''">
           jobs=#{jobs},
        </if>
        <if test="phone !=null and phone !=''">
            phone=#{phone},
        </if>
</set>
  where id=#{id}
</update>

​

上述代码中,使用了<set>和<if>元素相结合的方式来组装update语句.其中<set>元素会动态前置SET关键字,同时也会消除SQL语句中最后一个多余的逗号;<if>元素用于判断相应的字段是否传入值,如果传入的更新字段非空,就将此字段进行动态SQL组装,并更新此字段,否则此字段不执行更新.

5.<foreach>元素

<foreach>元素通常在构建IN条件语句时使用

<select id="findCustomerByIds" parameterType="List"
        resultType="com.itcast.po.Customer">
    select * from t_customer where id in 
     <foreach item="id" index="index" collection="list"
          open="(" separator="," close=")">
           #{id}
     </foreach>
</select>
<foreach>元素中的属性
属性名说明
item循环中当前的元素
index当前元素在集合的位置下标
collection配置的list是传递过来的参数类型(首字母小写),它可以是一个list,array,或者collection,Map集合的键,POJO包装类中数组或集合类型的属性名等
open/close配置的是以什么符号将这些集合元素包装起来
separator配置分隔符

 

 

 

 

 

 

 

6.<bind>元素

<bind>元素可以通过OGNL表达式来创建一个上下文变量,使用方式如下:

<!--根据客户名模糊查询客户信息-->
<select id="findCustomerByName" parameterType="com.itcast.po.Customer"
        resultType="com.itcast.po.Customer">
<!--_parameter.getUsername()也可直接写成传入的字段属性名,即username-->
     <bind name="pattern_username"
                       value="'%'+_parameter.getUsername()+'%'"/>
     select * from t_customer
       where 
      username like #{pattern_username}
</select>

 

测试代码:

​
​
/*
<bind>元素的使用,根据客户姓名模糊查询客户信息
*/
@Test
public void findCustomerByNameTest(){
     //通过工具类生成sqlsession对象
SqlSession sqlSession =MyBatisUtils.getSession();
//创建Customer对象,封装需要组合查询的条件
Customer customer=new Customer();
customer.setUsername("j");
//执行sqlSession 的查询方法,返回结果集
List<Customer> customers=sqlSession .selectList("com.itcast.mapper"+".CustomerMapper.findCustomerByName",customer);
//输出查询结果信息
for(Customer customer2:customers){
//打印输出结果
System.out.println(customer2);
}
//关闭sqlSession 
sqlSession.close();
}

​

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值