Springboot Mybatis 动态SQL

动态SQL

XML 复制代码
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.wzb.SqlImprove20240925.SQLImproveMapper">

    <!-- 将条件查询改成动态SQL形式 -->
    <!-- XML中,是对SQL语句进行拼接的,将若干SQL语句的条件,拼接成一条完整的SQL语句 -->
    <!-- <if>标签用于判断条件是否成立,用test属性进行条件判断,若条件为true,那么就拼接SQL,若为false,则不操作 -->
    <!--    <select id="sqlImprove" resultType="com.wzb.Pojo20240925.Emp">-->
    <!--        select * from emp-->
    <!--        where-->
    <!--        <if test="name != null">-->
    <!--            name like concat('%', #{name}, '%')-->
    <!--        </if>-->

    <!--        <if test="gender != -1">-->
    <!--            and gender = #{gender}-->
    <!--        </if>-->

    <!--        <if test="begin != null and end != null">-->
    <!--            and entrydate between #{begin} and #{end}-->
    <!--        </if>-->
    <!--        order by update_time desc-->
    <!--    </select>-->

    <!-- 上述代码看似完成了条件查询,但其实仍然有不足之处:
    1.若所有参数都是null,那么仍然会在SQL语句中拼接where,这是不符合SQL语法的
    2.若前面的是null,但是后面的参数不是null,那么会多拼接一个null,比如上面的代码:name是null;但是gender不是null
      那么就会拼接成"...... where and gender = #{gender}",这是错误的SQL语句
    -->

    <!-- 解决方法:<where>标签:
         <where>标签只会在子元素(参数)有内容的情况下,才会插入where子句,并且能够自动去除子句开头的and或者or -->


    <!-- 优化代码 -->
    <!-- 当参数没有传递(为null时),就不会将语句拼接成SQL语句,并且用了<where>标签,能够自动处理开头的and、or -->
    <select id="sqlImprove" resultType="com.wzb.Pojo20240925.Emp">
        select * from emp
        <where>
            <if test="name != null">
                and name like concat('%', #{name}, '%')
            </if>

            <if test="gender != -1">
                and gender = #{gender}
            </if>

            <if test="begin != null and end != null">
                and entrydate between begin and end
            </if>
        </where>
        order by update_time desc
    </select>
    <!-- 测试成功,成功实现动态SQL -->


    <!-- 实现动态更新员工信息 -->
<!--    <update id="updateImprove">-->
<!--        update emp-->
<!--        set-->
<!--        <if test="username != null">-->
<!--            username=#{username},-->
<!--        </if>-->
<!--        <if test="name != null">-->
<!--            name=#{name},-->
<!--        </if>-->
<!--        <if test="gender != -1">-->
<!--            gender=#{gender},-->
<!--        </if>-->
<!--        <if test="image != null">-->
<!--            image=#{image},-->
<!--        </if>-->
<!--        <if test="job != null">-->
<!--            job=#{job},-->
<!--        </if>-->
<!--        <if test="entrydate != null">-->
<!--            entrydate=#{entrydate},-->
<!--        </if>-->
<!--        <if test="deptId != null">-->
<!--            dept_id=#{deptId},-->
<!--        </if>-->
<!--        <if test="updateTime != null">-->
<!--            update_time=#{updateTime}-->
<!--        </if>-->
<!--        where id = #{id}-->
<!--    </update>-->

    <!-- 这个代码会出现问题,若只传递前面的参数,不传递最后一个参数,那么将会多出一个","(因为每一个拼接语句的末尾都有个逗号,
    只有最后一1个拼接语句没有),所以说只要不传递最后一个参数,就会发生SQL语句语法错误 -->

    <!-- 解决方法:使用标签<set>
         在update语句中使用<set>标签,会删除掉额外的逗号,避免SQL语法错误 -->

    <update id="updateImprove">
        update emp
        <set>
            <if test="username != null">
                username=#{username},
            </if>
            <if test="name != null">
                name=#{name},
            </if>
            <if test="gender != -1">
                gender=#{gender},
            </if>
            <if test="image != null">
                image=#{image},
            </if>
            <if test="job != null">
                job=#{job},
            </if>
            <if test="entrydate != null">
                entrydate=#{entrydate},
            </if>
            <if test="deptId != null">
                dept_id=#{deptId},
            </if>
            <if test="updateTime != null">
                update_time=#{updateTime}
            </if>
        </set>
        where id = #{id}
    </update>

    <!-- 这样可以解决update语句后多","的问题 -->

    <!-- 小结:
         <if>标签可以用于判断条件是否成立,若条件为true,那么拼接对应的SQL语句
         <where>标签代替where,只会在子元素不为null的时候才插入where子句,并且能够自动去除子句开头的多余的and和or
         <set>标签代替set在update语句中使用,可以动态的插入update子句,并且能删除额外的"," -->

    <!-- 使用<foreach>标签达到删除多条语句的效果 -->
    <!-- <foreach collection="集合名称" item="集合遍历出来的元素", separator="每一次遍历使用的分隔符"
          open="遍历开始之前拼接的片段" close="遍历结束后拼接的片段"> -->
    <delete id="deleteImprove">
        delete from emp where id in
        <foreach collection="ids" item="id" separator="," open="(" close=")">
            #{id}
        </foreach>
    </delete>
    <!-- 成功使用<foreach>完成批量删除 -->

    <!-- 在XML映射文件中配置SQL,有时会出现很多重复的片段,那么就会导致很多冗余的代码 -->

</mapper>

SQLImproveMapper

java 复制代码
package com.wzb;

import com.wzb.MybatisExercise20240925.EmpMapper;
import com.wzb.MybatisXmlExercise20240925.XmlMapper;
import com.wzb.Pojo20240925.Emp;
import com.wzb.SqlImprove20240925.SQLImproveMapper;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

@SpringBootTest
class SpringbootExercise20240925ApplicationTests {

    @Autowired
    private EmpMapper empMapper;

    @Autowired
    private XmlMapper xmlMapper;

    @Autowired
    private SQLImproveMapper sqlImproveMapper;

    // 增
//    @Test
//    public void insertEmp() {
//        Emp emp = new Emp();
//        emp.setUsername("black");
//        emp.setName("布莱克");
//        emp.setGender((short)1);
//        emp.setImage("2.jpg");
//        emp.setJob((short)2);
//        emp.setEntrydate(LocalDate.of(2000, 1, 1));
//        emp.setCreateTime(LocalDateTime.now());
//        emp.setUpdateTime(LocalDateTime.now());
//
//        empMapper.insertEmp(emp);
//    }

//    // 删
//    @Test
//    public void deleteEmp() {
//        empMapper.deleteEmp(20);
//    }
//
//    // 改
//    @Test
//    public void updateEmp() {
//        Emp emp = new Emp();
//        emp.setId(19);
//        emp.setUsername("gaiya");
//        emp.setName("盖亚");
//        emp.setGender((short)1);
//        emp.setImage("2.jpg");
//        emp.setJob((short)2);
//        emp.setEntrydate(LocalDate.of(2000, 1, 1));
//        emp.setCreateTime(LocalDateTime.now());
//        emp.setUpdateTime(LocalDateTime.now());
//
//        empMapper.updateEmp(emp);
//    }
//
//    // 查
//    @Test
//    public void selectEmp() {
//        Emp emp = empMapper.selectEmp(19);
//        System.out.println(emp);
//    }

    @Test
    public void XmlConditionSelect() {
        List<Emp> empList = xmlMapper.conditionSelect("张", (short) 1, null, null
                /*LocalDate.of(2000, 1, 1), LocalDate.of(2024,1,1)*/);
        for (Emp emp : empList) {
            System.out.println(emp);
        }

    }

    @Test
    public void SqlImprove() {
        List<Emp> empList = sqlImproveMapper.sqlImprove(null, (short) -1, null, null);
        for (Emp emp : empList) {
            System.out.println(emp);
        }
    }

    @Test
    public void updateEmp() {
        Emp emp = new Emp();
        emp.setUsername("tom2");
        sqlImproveMapper.updateImprove(emp);
    }

    @Test
    public void deleteEmp() {
        List<Integer> ids = new ArrayList<>();
        Collections.addAll(ids, 18,19,26,27);
        sqlImproveMapper.deleteImprove(ids);
    }
}
相关推荐
欢乐少年19042 小时前
SpringBoot集成Sentry日志收集-3 (Spring Boot集成)
spring boot·后端·sentry
夏天的味道٥3 小时前
使用 Java 执行 SQL 语句和存储过程
java·开发语言·sql
冰糖码奇朵4 小时前
大数据表高效导入导出解决方案,mysql数据库LOAD DATA命令和INTO OUTFILE命令详解
java·数据库·sql·mysql
好教员好4 小时前
【Spring】整合【SpringMVC】
java·spring
迷路的小犀牛4 小时前
【MYSQL数据库异常处理】执行SQL语句报超时异常
数据库·sql·mysql
曹天骄5 小时前
使用 MyBatis XML 和 QueryWrapper 实现动态查询
xml·mybatis
浪九天5 小时前
Java直通车系列13【Spring MVC】(Spring MVC常用注解)
java·后端·spring
小斌的Debug日记6 小时前
框架基本知识总结 Day16
redis·spring
m0_748246876 小时前
maven导入spring框架
数据库·spring·maven