Mybatis动态SQL

文章目录

  • 一、if标签
  • 二、where标签
  • 三、trim标签
  • 四、set标签
  • 五、choose标签


一、if标签

需求:多条件查询
可能的条件包括:品牌(brand)、指导价格(guide_price)、汽车类型(car_type)
接口

/**
     * 多条件查询
     * @param brand
     * @param guidePrice
     * @param carType
     * @return
     */
    List<Car> selectByMultiCondition(@Param("brand")String brand,@Param("guidePrice") Double guidePrice,@Param("carType") String carType);

mapper.xml:
1、if标签中test属性是必须的
2、if标签中test属性的值是false或者true
3、如果test是true,则if标签中的sql语句就会拼接,反之则不会
4、test属性中可以使用的是:
* 当使用了@Param注解,那么test中要出现的是@Param注解指定的参数名。@Param(“brand”),那么这里只能使用brand
*当没有使用@Param注解,那么test中要出现的是:param1 param2 param3 arg0 arg1 arg2
*当使用了POJO,那么test中要出现的是POJO类的属性名
5、在mybatis的动态SQL当中,不能使用&& 只能使用and

<select id="selectByMultiCondition" resultType="car">
    select * from t_car where
    
    <if test="brand != null and brand != ''">
        brand like "%"#{brand}"%"
    if>
    <if test="guidePrice != null and guidePrice != ''">
        and guide_price > #{guidePrice}
    if>
    <if test="carType != null and carType != ''">
        and car_type = #{carType}
    if>
select>

测试:

@Test
    public void testSelectByMultiCondition() throws IOException {
        SqlSession session = SqlSessionUtil.openSession();
        CarMapper mapper = session.getMapper(CarMapper.class);
        //假设三个条件都不是空
        //List cars = mapper.selectByMultiCondition("川",10.0,"能能源");

        //假设三个条件都是空
        //List cars = mapper.selectByMultiCondition("",null,"");

        //假设后两个条件不是空,第一个条件是空
        //List cars = mapper.selectByMultiCondition("",10.0,"能能源");

        //假设第一个条件不是空,后两个条件是空
        List<Car> cars = mapper.selectByMultiCondition("川",null,"");
        cars.forEach(car -> {
            System.out.println(car);
        });
        session.close();
    }

运行结果:
1、假设三个条件都不为空
在这里插入图片描述
2、假设三个条件都为空
在这里插入图片描述
SQL语句语法报错,当三个条件都为null时:select * from t_car where…
where 多余了不符合规定,解决方法:where 1=1 查询所有结果。
Mybatis动态SQL_第1张图片
3、假设后两个条件不是空,第一个条件是空
Mybatis动态SQL_第2张图片
4、假设第一个条件不是空,后两个条件是空
有语法问题:少一个and,加上去
在这里插入图片描述
有语法问题:少一个and,加上去
在这里插入图片描述
最终的mapper.xml文件:

<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>
    <if test="carType != null and carType != ''">
        and car_type = #{carType}
    if>
select>

二、where标签

where标签的作用:让where子句更加智能
*所有条件都为空时,where标签保证不会生成where子句
*自动去除某些条件前面多余的and或or。
接口

  /**
     * 多条件查询
     * @param brand
     * @param guidePrice
     * @param carType
     * @return
     */
    List<Car> selectByMultiConditionWithWhere(@Param("brand")String brand,@Param("guidePrice") Double guidePrice,@Param("carType") String carType);

mapper.xml

<select id="selectByMultiConditionWithWhere"  resultType="car">
    select * from t_car
    
    <where>
        <if test="brand != null and brand != ''">
            brand like "%"#{brand}"%"
        if>
        <if test="guidePrice != null and guidePrice != ''">
            and guide_price > #{guidePrice}
        if>
        <if test="carType != null and carType != ''">
            and car_type = #{carType}
        if>
    where>
select>

测试

@Test
    public void testSelectByMultiConditionWithWhere() throws IOException {
        SqlSession session = SqlSessionUtil.openSession();
        CarMapper mapper = session.getMapper(CarMapper.class);
        //假设三个条件都不是空
        //List cars = mapper.selectByMultiConditionWithWhere("川",10.0,"能能源");

        //假设三个条件都是空
        List<Car> cars = mapper.selectByMultiConditionWithWhere("",null,"");

        //假设后两个条件不是空,第一个条件是空
        //List cars = mapper.selectByMultiConditionWithWhere("",10.0,"能能源");

        //假设第一个条件不是空,后两个条件是空
        //List cars = mapper.selectByMultiConditionWithWhere("川",null,"");
        cars.forEach(car -> {
            System.out.println(car);
        });
        session.close();
    }

运行结果
四种情况都可正常执行。

三、trim标签

接口

  /**
     * 多条件查询 使用trim标签
     * @param brand
     * @param guidePrice
     * @param carType
     * @return
     */
    List<Car> selectByMultiConditionWithTrim(@Param("brand")String brand,@Param("guidePrice") Double guidePrice,@Param("carType") String carType);

mapper.xml
trim标签:
*prefix:加前缀
*suffix:加后缀
*prefixOverrides:删除前缀
*suffixOverrides:删除后缀

    <select id="selectByMultiConditionWithTrim"  resultType="car">
        select * from t_car
        
        <trim prefix="where" suffixOverrides="and|or">
            <if test="brand != null and brand != ''">
                brand like "%"#{brand}"%" and
            if>
            <if test="guidePrice != null and guidePrice != ''">
                guide_price > #{guidePrice} and
            if>
            <if test="carType != null and carType != ''">
                and car_type = #{carType}
            if>
            trim>
    select>

< trim prefix=“where” suffixOverrides=“and|or”>意思包含在trim标签里所有内容的前边加上前缀where,并且去掉trim标签里的后缀and或or。

测试

@Test
    @Test
    public void testSelectByMultiConditionWithTrim() throws IOException {
        SqlSession session = SqlSessionUtil.openSession();
        CarMapper mapper = session.getMapper(CarMapper.class);
        //假设三个条件都不是空
        //List cars = mapper.selectByMultiConditionWithTrim("川",10.0,"能能源");

        //假设三个条件都是空
        List<Car> cars = mapper.selectByMultiConditionWithTrim("",null,"");

        //假设后两个条件不是空,第一个条件是空
        //List cars = mapper.selectByMultiConditionWithTrim("",10.0,"能能源");

        //假设第一个条件不是空,后两个条件是空
        //List cars = mapper.selectByMultiConditionWithTrim("川",null,"");
        cars.forEach(car -> {
            System.out.println(car);
        });
        session.close();
    }

运行结果
四种情况都可正常执行。

四、set标签

主要使用在update语句当中,用来生成set关键字,同时去掉最后多余的”,“
比如我们只更新提交的不为空的字段,如果提交的数据是空或者” “,那么这个字段我们将不更新。

接口

    /**
     * 使用set标签
     * @param car
     * @return
     */
    int updateBySet(Car car);

mapper.xml:
与正常的update标签进行对比:

<update id="updateById">
    update t_car set
        car_num = #{carNum},
        brand = #{brand},
        guide_price = #{guidePrice},
        produce_time = #{produceTime},
        car_type = #{carType}
update>

这个会出现的情况就是当在测试时传进去的参数new Car(1L,null,null,null,null,null,“燃油车”);我们的目的是只想修改car_type,其他都不变。但是执行完上述代码之后,除了id和car_type字段其他都变为空。
使用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="carType !=null and carType != ''">
            car_type = #{carType},
        if>
    set>
    where 
        id =#{id}
update>

测试

    @Test
    public void testUpdateBySet() throws IOException {
        SqlSession session = SqlSessionUtil.openSession();
        CarMapper mapper = session.getMapper(CarMapper.class);
        Car car = new Car(13L,"1004",null,60.0,null,null);
        int count = mapper.updateBySet(car);
        System.out.println(count);
        session.commit();
        session.close();
    }

运行结果
执行前: (id=13的数据)
Mybatis动态SQL_第3张图片
执行后:
Mybatis动态SQL_第4张图片

五、choose标签

等同于:
if(){
}else if(){
}else if(){
}else{
}
只有一个分支会被选择。
需求:先根据品牌查询,如果没有提供品牌,再根据指导价查询,如果没有提供指导价,就根据生产日期查询。
接口

	/**
     * 使用choose when otherwise标签
     * @param brand
     * @param guidePrice
     * @param carType
     * @return
     */
    List<Car> selectByChoose(@Param("brand") String brand,@Param("guidePrice") Double guidePrice,@Param("carType") String carType);


mapper.xml

<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 test="carType !=null and carType!=''">
                car_type = #{carType}
            otherwise>
        choose>
    where>
select>

测试

    @Test
    public void testSelectByChoose() throws IOException {
        SqlSession session = SqlSessionUtil.openSession();
        CarMapper mapper = session.getMapper(CarMapper.class);
        List<Car> cars =  mapper.selectByChoose("宝马",null,null);
        cars.forEach(car -> {
            System.out.println(car);
        });
        session.close();
    }

运行结果
若三个参数都不为空,则以第一个参数为主。
在这里插入图片描述

若三个参数都为空,则条件最后会落在carType上,此时carType=null;也就是查不到任何数据
在这里插入图片描述

注意:choose when otherwise 三个标签必须一起使用


你可能感兴趣的:(mybatis,sql,数据库)