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);
    }
}
相关推荐
路在脚下@1 分钟前
spring boot的配置文件属性注入到类的静态属性
java·spring boot·sql
啦啦右一3 分钟前
Spring Boot | (一)Spring开发环境构建
spring boot·后端·spring
森屿Serien4 分钟前
Spring Boot常用注解
java·spring boot·后端
苹果醋31 小时前
React源码02 - 基础知识 React API 一览
java·运维·spring boot·mysql·nginx
盛派网络小助手2 小时前
微信 SDK 更新 Sample,NCF 文档和模板更新,更多更新日志,欢迎解锁
开发语言·人工智能·后端·架构·c#
∝请叫*我简单先生2 小时前
java如何使用poi-tl在word模板里渲染多张图片
java·后端·poi-tl
荆州克莱3 小时前
mysql中局部变量_MySQL中变量的总结
spring boot·spring·spring cloud·css3·技术
zquwei3 小时前
SpringCloudGateway+Nacos注册与转发Netty+WebSocket
java·网络·分布式·后端·websocket·网络协议·spring
dessler4 小时前
Docker-run命令详细讲解
linux·运维·后端·docker
火烧屁屁啦4 小时前
【JavaEE进阶】初始Spring Web MVC
java·spring·java-ee