MyBatis 动态SQL

为什么需要动态SQL

在一些特殊的业务场景下,需要用户选择某些标签或选项,对搜索的东西进行过滤,更好的完善用户的体验,这个时候童鞋们就需要使用到动态的SQL进行CRUD啦。

在这里插入图片描述

1. if标签

package com.powernode.mybatis.mapper;

import com.powernode.mybatis.pojo.Car;
import org.apache.ibatis.annotations.MapKey;
import org.apache.ibatis.annotations.Param;

import java.util.List;
import java.util.Map;

public interface CarMapper {
	/**
     * 根据多条件查询
     * @param brand
     * @param guidePrice
     * @return
     */
    List<Car> selectByMultiCondition(@Param("brand") String brand, @Param("guidePrice") Double guidePrice);
}

<select id="selectByMultiCondition" resultType="car">
	select * from t_car where 1 = 1
	<if test="brand != null and brand != ''">
		and brand like "%"#{brand}"%"
	</if>
	<if test="guidePrice != null and guidePrice != ''">
		and guide_price > "%"#{guidePrice}"%"
	</if>
</select>
package com.powernode.mybatis.test;

import com.powernode.mybatis.mapper.CarMapper;
import com.powernode.mybatis.pojo.Car;
import com.powernode.mybatis.utils.SqlSessionUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.ArrayList;
import java.util.List;

public class CarMapperTest {
	@Test
    public void testSelectByMultiCondition() {
        SqlSession sqlSession = SqlSessionUtil.openSession();
        CarMapper mapper = sqlSession.getMapper(CarMapper.class);
		//List<Car> cars = mapper.selectByMultiCondition("比亚迪", 2.0, "新能源");
        List<Car> cars = mapper.selectByMultiCondition("", null, "");
        for (Car car :
                cars) {
            System.out.println(car);
        }
        sqlSession.close();
    }
}

where 1 = 1是为了防止当brand和guidePrice都为空的时候出现select * from t_car where,以及当其中一个为空时出现select * from t_car where and ...的sql语句错误

注意点:

  • if标签中的test属性是必须的,并且test属性的值只能是布尔值
  • test属性中可以使用的是:
    • 使用@Param注解,那么test中要出现的是@Param注解指定的参数名
    • 没有使用@Param注解,那么test中要出现的是arg0 arg1… 或者 param1 param2…
    • 使用了POJO类,那么test中出现的是POJO类中的属性名
  • 在mybatis的动态SQL中,不能使用&&,只能使用and或or

2. where标签

mybatis为了让sql语句的可读性更强,不再使用1=1这种多余且并没有什么用处的语句,提供了where标签,让where子句更加动态智能。

上面的sql语句就可以写成下面的形式

<select id="selectByMultiCondition" resultType="car">
	select * from t_car 
	<where>
		<if test="brand != null and brand != ''">
			and brand like "%"#{brand}"%"
		</if>
		<if test="guidePrice != null and guidePrice != ''">
			and guide_price > "%"#{guidePrice}"%"
		</if>
	</where>
</select>
  • 所有条件都为空时,where标签不会生成where子句
  • where标签会自动去除某些条件中前面多余and或or

3. trim标签

在MyBatis中不仅可以使用where标签对where子句进行动态智能控制,使用trim标签同样可以达到预期的结果。

  <select id="selectByMultiConditionWithTrim" resultType="car">
        select * from t_car
        <!--prefix="where" 是在trim标签所有内容的前面添加where-->
        <!--suffixOverrides="and|or" 把trim标签中内容的后缀and或or去掉-->
        <trim prefix="where" suffix="" prefixOverrides="" suffixOverrides="and|or" >
            <if test="brand != null and brand != ''">
                brand like "%"#{brand}"%" and
            </if>
            <if test="guidePrice != null and guidePrice != ''">
                guide_price > #{guidePrice}
            </if>
        </trim>
    </select>

trim标签中的属性

属性说明
prefix在trim标签中的sql语句前添加内容
suffix在trim标签中的sql语句后添加内容
prefixOverrides删除掉前缀
suffixOverrides删除掉后缀

4. set标签

set标签用在update语句当中,生成set关键字,并且可以去掉最后多余的“,”

 <update id="updateBySet">
        update t_car
        <set>
            <if test="carNum !=null and carNum !=''">car_num = #{carNum},</if>
            <if test="brand !=null and brand !=''">brand = #{brand},</if>
            <if test="guidePrice !=null and guidePrice !=''">guide_price = #{guidePrice},</if>
            <if test="produceTime !=null and produceTime !=''">produce_time = #{produceTime},</if>
            <if test="carType !=null and carType !=''">car_type = #{carType},</if>
        </set>
        where id = #{id}
    </update>

5.choose when otherwise

<choose>
	<when></when>
	<when></when>
	<otherwise></otherwise>
</choose>

等同于

if(){

}else if(){

}else{

}

其中只有一个分支会被选择,when可以写多个,但是otherwise只能写一个。

    <select id="selectByChoose" resultType="car">
        select * from t_car
        <where>
            <choose>
                <when test="brand!=null and brand!=''">
                    brand like "%"#{brand}"%"
                </when>
                <when test="guidePrice!=null and guidePrice!=''">
                    guide_price > "%"#{guidePrice}"%"
                </when>
                <otherwise>
                    car_type = "%"#{carType}"%"
                </otherwise>
            </choose>
        </where>
    </select>

6. foreach标签

MyBatis中的foreach标签用于循环数组或集合,动态的生成sql

批量删除

用in来删除

<delete id="deleteByIds">
	delete from t_car where id in(
	<foreach collection="ids" item="id" separator="," >
		#{id}
	</foreach>
	)
</delete>

等同于

 <delete>
		delete from t_car where id in
       	<foreach collection="ids" item="id" separator="," open="(" close=")">
            #{id}
        </foreach>
</delete>

foreach标签中的属性

属性说明
collection指定数组或集合(使用@Param注解时,可以使用@Param注解指定的值)
item代表数组或集合中的元素
separator循环之间的分隔符
openforeach循环拼接的所有sql语句的最前面以什么开始
closeforeach循环拼接的所有sql语句的最后面以什么结束

用or来删除

 <delete>
		delete from t_car where
       	<foreach collection="ids" item="id" separator="or" >
            id=#{id}
        </foreach>
</delete>

参考文档:
https://blog.csdn.net/Aibiabcheng/article/details/118423189?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522166918824716800215096839%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=166918824716800215096839&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2alltop_positive~default-1-118423189-null-null.142v66control,201v3control,213v2t3_control1&utm_term=%E5%8A%A8%E6%80%81SQL&spm=1018.2226.3001.4187

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值