mybatis if 标签使用总结

在项目开发中,mybatis <if> 标签使用广泛,本文讲解if标签的两种使用方式

其一、使用 <if> 标签判断某一字段是否为空

其二、使用 <if> 标签判断传入参数是否相等

 

具体代码如下

数据库表结构和数据

实体类

package com.demo.bean;

public class Commodity {
	
	private String name;
	
	private String date;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getDate() {
		return date;
	}

	public void setDate(String date) {
		this.date = date;
	}

	@Override
	public String toString() {
		return "Com [name=" + name + ", date=" + date + "]";
	}
	
}

mapper层

package com.demo.mapper;

import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import com.demo.bean.Commodity;
@Mapper
public interface CommodityMapper {

	List<Commodity> getListByDate(Commodity commodity);
	
	List<Commodity> getListByStartDateAndEndDate(@Param("startDate")String startDate, @Param("endDate")String endDate);
}

mapper.xml文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.demo.mapper.CommodityMapper">
	
	<resultMap id="BaseResultMap" type="com.demo.bean.Commodity">
		<id column="name" property="name" jdbcType="VARCHAR" />
		<result column="date" property="date" jdbcType="VARCHAR" />
	</resultMap>
	
	<select id="getListByDate" resultMap="BaseResultMap">
	  select * from commodity where 1 = 1
	  <if test="date != null and date != ''">
	    and date = #{date}
	  </if> 
	</select>
	
	<select id="getListByStartDateAndEndDate" resultMap="BaseResultMap">
	  select * from commodity where 1 = 1
	  <if test="#{startDate}.toString() != #{endDate}.toString()">
	    and date between #{startDate} and #{endDate}
	  </if>
	</select>
	
</mapper>

注意:mybatis 等值判断的 tostring()方法 (上边代码中第二个select中的toString()方法)

controller层

package com.demo.controller;

import java.util.HashMap;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import com.demo.bean.Commodity;
import com.demo.mapper.CommodityMapper;

@RestController
public class DemoController {

	@Autowired
	private CommodityMapper comMapper;
	
	@RequestMapping(value = "/commodity")
	public Object commodity() {
		Map<String, Object> map = new HashMap<String, Object>();
		Commodity com =new Commodity();
		com.setDate("2018-10-12");
		map.put("res", comMapper.getListByDate(com));
		return map;
	}
	
	@RequestMapping(value = "/between")
	public Object commodityBetween() {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("res", comMapper.getListByStartDateAndEndDate("2018-10-09", "2018-10-13"));
		return map;
	}
}

测试

1、访问  http://localhost:9000/commodity  

2、访问  http://localhost:9000/between

 

<think>嗯,用户想了解MyBatis中如何使用if-else实现动态SQL。首先,我得回忆一下MyBatis的动态SQL标签。根据之前的引用资料,MyBatis主要提供了<if>、<choose>、<when>、<otherwise>这些标签。 用户提到的是if-else,但MyBatis并没有直接的<else>标签。那该怎么实现类似if-else的效果呢?我记得在引用[3]中提到,<choose>、<when>、<otherwise>类似于Java的switch-case或者if-else结构。所以可能需要用<choose>标签来组合多个条件。 比如,用户可能想根据不同的条件添加不同的SQL片段。例如,当条件A满足时,执行某个操作,否则执行另一个操作。这时候就可以用<choose>包裹多个<when>和一个<otherwise>。每个<when>对应一个条件,最后的<otherwise>作为默认情况。 另外,引用[2]中的例子也展示了如何使用<choose>来模拟if-else。例如,在查询用户时,根据传入的roleType不同,添加不同的查询条件。如果roleType是admin,就查所有用户;如果是user,就查普通用户;否则查VIP用户。 还有,用户可能想知道单独的<if>标签如何使用。比如在WHERE语句中动态添加条件,这时候可以用多个<if>标签,但这样更像多个if语句,而不是if-else。这时候需要确保条件之间不会冲突,或者结合<where>标签来避免语法错误。比如引用[5]中的例子,使用1=1来避免多余的AND问题,然后每个条件用<if>判断是否添加。 另外,可能需要注意MyBatis的动态SQL是如何解析OGNL表达式的,比如在test属性中的条件写法是否正确。例如,判断字符串是否为空要用!= null和!= '',如引用[4]中的示例。 用户可能需要具体的示例,所以应该给出几种常见的使用场景,比如在WHERE子句中使用<choose>实现分支选择,或者在UPDATE语句中根据不同条件更新不同字段。 还要注意,虽然用户问的是if-else,但MyBatis中更常见的是使用<choose>来实现多分支选择,而单独的<if>标签用于单条件判断。因此,需要明确说明这两种情况的不同用法,并提供相应的代码示例。 可能还需要提到性能方面的考虑,比如动态SQL的拼接是否会影响效率,或者如何优化复杂的条件判断。不过用户的问题主要是使用方法,所以重点放在示例和标签的组合使用上。 总结一下,回答的结构应该包括: 1. 介绍MyBatis中实现条件分支的标签:<choose>, <when>, <otherwise>。 2. 提供示例,比如根据不同的参数值生成不同的SQL条件。 3. 单独<if>标签使用场景和示例。 4. 可能需要注意的问题,比如OGNL表达式的正确写法,避免SQL语法错误的方法,如使用<where>标签或1=1技巧。 5. 相关问题的推荐,帮助用户进一步学习。</think>### MyBatisif-else动态SQL实现方法 在MyBatis中,虽然没有直接的`<else>`标签,但可以通过以下两种方式实现类似if-else的逻辑: --- ### 一、使用`<choose>`+`<when>`+`<otherwise>`组合 这是MyBatis官方推荐的**多条件分支**实现方式,类似于Java中的`switch-case`或`if-else if-else`结构。 #### 语法示例 ```xml <select id="selectUsers" resultType="User"> SELECT * FROM users <where> <choose> <when test="roleType == 'admin'"> <!-- 条件1 --> AND is_admin = 1 </when> <when test="roleType == 'user'"> <!-- 条件2 --> AND is_vip = 0 </when> <otherwise> <!-- 默认分支 --> AND is_vip = 1 </otherwise> </choose> </where> </select> ``` #### 执行逻辑 1. 按顺序判断`<when>`中的条件表达式 2. **仅执行第一个满足条件的`<when>`块** 3. 若无满足条件的`<when>`,则执行`<otherwise>`块 4. `<otherwise>`是可选标签[^3] --- ### 二、通过多个`<if>`标签模拟if-else 在特定场景下,可以通过**条件互斥**的方式实现类似效果: ```xml <update id="updateUser"> UPDATE users <set> <if test="status != null">status = #{status},</if> <if test="status == null">last_login_time = NOW(),</if> </set> WHERE id = #{id} </update> ``` *注意:需要确保条件间具有互斥性,否则可能出现多个分支同时生效的情况[^4]* --- ### 三、典型应用场景 1. **WHERE条件分支** ```xml <select id="findByCondition" resultType="Blog"> SELECT * FROM blog <where> <choose> <when test="state == 1"> <!-- 草稿状态 --> AND draft = 1 </when> <when test="state == 2"> <!-- 已发布状态 --> AND published = 1 AND deleted = 0 </when> <otherwise> <!-- 默认查询非删除内容 --> AND deleted = 0 </otherwise> </choose> </where> </select> ``` 2. **UPDATE字段选择** ```xml <update id="updateSelective"> UPDATE employee <set> <choose> <when test="department != null"> <!-- 部门变更时更新关联字段 --> dept_id = #{department.id}, manager_id = #{department.managerId}, </when> <otherwise> <!-- 普通更新 --> salary = #{salary}, title = #{title} </otherwise> </choose> </set> WHERE id = #{id} </update> ``` --- ### 四、注意事项 1. **OGNL表达式语法**: - 字符串比较:`test="type == 'vip'"` - 非空判断:`test="username != null and username != ''"`[^4] - 数值判断:`test="age > 18"` 2. **避免SQL语法错误**: - 在WHERE子句中使用`<where>`标签自动处理首尾AND/OR - 在UPDATE语句中使用`<set>`标签自动去除末尾逗号[^5] 3. **性能优化**: - 将高概率条件放在靠前位置 - 避免在test表达式内进行复杂计算 ---
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

悟世君子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值