当前位置: 首页 > article >正文

Springboot Mybatis 动态SQL

        动态SQL

<?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

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);
    }
}

 


http://www.kler.cn/news/325524.html

相关文章:

  • 【RocketMQ】消费失败重试与死信消息
  • 低代码平台中的宿主概念解析与字典、角色、岗位及权限管理
  • 金属增材制造咋突破?纳米纹理粉末如何助力金属增材制造?
  • C++ bitset(位图)的模拟实现
  • JS设计模式之状态模式:优雅地管理应用中产生的不同状态
  • Java并发:互斥锁,读写锁,公平锁,Condition,StampedLock
  • 穿越数字迷雾:探索IT领域的无限可能
  • 后端开发面试题8(附答案)
  • k8s_资源管理介绍
  • Spring Boot驱动的在线房产租赁服务
  • next 从入门到精通
  • 【RabbitMQ】幂等性、顺序性
  • js 如何监听 body 内容是否改变
  • 【WPF】桌面程序开发之窗口的用户控件详解
  • MATLAB绘图基础
  • 利用 PostgreSQL 构建 RAG 系统实现智能问答
  • 小程序视频编辑SDK解决方案,轻量化视频制作解决方案
  • 三菱PLC数据 转 profinet IO项目案例
  • 使用 Docker 部署 RStudio 的终极教程
  • Spring Boot 点餐系统:一键订餐解决方案
  • C++之Person类中调用Date类
  • 电脑使用adb工具连接手机,全文完整教程
  • MFC - 常用基础控件
  • 高防服务器如何抵御网络攻击?
  • RT-DETR改进策略:BackBone改进|PoolFormer赋能RT-DETR,视觉检测性能显著提升的创新尝试
  • 11.C++程序中的常用函数
  • 【含文档】基于Springboot+Vue的个性化推荐电商平台(含源码+数据库+lw)
  • 【网络安全】公钥密码体制
  • 关于QSizeGrip在ui界面存在布局的情况下的不显示问题
  • 绿色新纪元:光伏技术飞跃与能源体系重塑