后端数据库开发高级之通过在xml文件中映射实现动态SQL

简介: 后端数据库开发高级之通过在xml文件中映射实现动态SQL

if where标签

一个非常重要的功能

随着用户的输入或者是外部条件的变化而改变的SQL语句

我们称为SQL语句

只有传形参的有值 其他的属性都是null

所以并没有查询到数据

我们不难免会发现我们先前的

SQL的语句是固定死的

这样局限性太高

在xml映射文件中使用if标签可以实现动态SQL

SQL语句会根据传入参数的数量而变化

if标签用来做条件判断 这个条件要声明

<?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="org.example.mybatis.mapper.UserMapper">
 
    <!--动态语句-->
    <select id="list" resultType="org.example.mybatis.pojo.User">
        select * from emp
        where
 
        <if test="name !=null">
            name like concat('%',#{name},'%')
        </if>
 
        <if test="gender !=null">
            and gender = #{gender}
        </if>
 
        <if test="begin !=null and end !=null ">
            and entrydate between #{begin} and #{end}
        </if>
 
        order by update_time desc
    </select>
 
</mapper>

将SQL语句进行判断后填充

where标签 可以去除多余的and 和 where

<?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="org.example.mybatis.mapper.UserMapper">
 
    <!--动态语句-->
    <select id="list" resultType="org.example.mybatis.pojo.User">
        select * from emp
        <where>
 
            <if test="name !=null">
                name like concat('%',#{name},'%')
            </if>
 
            <if test="gender !=null">
                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>
 
</mapper>

if 案例

更新三个字段

首先赋值指定内容的字段

接着删掉不需要修改的字段

启动更新

数据库表中的数据完成了更新

但是其余字段是null

根据id去更新时 我们写是写死的 每一次都要传递更新

传递就去更新字段 不传递字段值就是null

这样子的更新并不灵活 我们要将员工信息更细改为动态更新

动态更新员工 如果传递时有数值 就更新 没有传递值 就还是默认数值

XML文件里映射并书写动态SQL语句

指定id 就

是映射的方法名 即SQL语句的标签 生成的update标签是根据书写的方法名自动识别的

动态映射

<?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="org.example.mybatis.mapper.UserMapper">
 
    <update id="update">
        <!--动态更新SQL-->
        update emp
        set
        <if test="username !=null ">username=#{username},</if>
        <if test="password !=null ">password=#{password},</if>
        <if test="name !=null ">name=#{name},</if>
        <if test="gender !=null ">gender=#{gender},</if>
        <if test="image !=null ">image=#{image},</if>
        <if test="job !=null ">job=#{job},</if>
        <if test="deptID !=null ">dept_id=#{deptID},</if>
        <if test="entryDate !=null ">entrydate=#{entryDate},</if>
        <if test="creatTime !=null ">create_time=#{creatTime},</if>
        <if test="updateTime !=null ">update_time=#{updateTime}</if>
 
        where id=#{id}
 
    </update>
 
    <!--动态语句-->
    <select id="list" resultType="org.example.mybatis.pojo.User">
        select * from emp
        <where>
 
            <if test="name !=null">
                name like concat('%',#{name},'%')
            </if>
 
            <if test="gender !=null">
                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>
 
</mapper>

写在Mapper接口里的

package org.example.mybatis;
 
 
import org.example.mybatis.mapper.UserMapper;
import org.example.mybatis.pojo.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
 
import java.sql.*;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
 
@SpringBootTest //springboot整合单元测试的注解
class MybatisApplicationTests {
 
    @Autowired
    //声明接口类型的对象 将此对象注入进来
    private UserMapper userMapper;
 
 
 
    @Test
    public void testList() {
//        List<User> userList = userMapper.list("张", (short) 1,
//                LocalDate.of(2010, 1, 1),
//                LocalDate.of(2020, 1, 1));
        List<User> userList =userMapper.list("张",null,null,null);
        System.out.println(userList);
    }
 
    @Test
    //动态更新员工数据 更新ID为14的员工 更新Username name gender
        public void testUpdata() {
 
        User user = new User();
 
        user.setId(13);
        user.setUsername("Dduo1");
        user.setName("多多");
        user.setGender((short) 1);
        user.setCreatTime(LocalDateTime.now());
        user.setUpdateTime(LocalDateTime.now());
 
        //执行新增员工信息的操作
        userMapper.update(user);
    }
 
}

数据库中ID为13的员工信息完成了更新

set标签

<?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="org.example.mybatis.mapper.UserMapper">
 
    <update id="update">
        <!--动态更新SQL-->
        update emp
        <!--用来替换set关键字 可以更新所有的标签并去除逗号-->
        <set>
            <if test="username !=null ">username=#{username},</if>
            <if test="password !=null ">password=#{password},</if>
            <if test="name !=null ">name=#{name},</if>
            <if test="gender !=null ">gender=#{gender},</if>
            <if test="image !=null ">image=#{image},</if>
            <if test="job !=null ">job=#{job},</if>
            <if test="deptID !=null ">dept_id=#{deptID},</if>
            <if test="entryDate !=null ">entrydate=#{entryDate},</if>
            <if test="creatTime !=null ">create_time=#{creatTime},</if>
            <if test="updateTime !=null ">update_time=#{updateTime}</if>
        </set>
        where id=#{id}
 
    </update>
 
    <!--动态语句-->
    <select id="list" resultType="org.example.mybatis.pojo.User">
        select * from emp
        <where>
 
            <if test="name !=null">
                name like concat('%',#{name},'%')
            </if>
 
            <if test="gender !=null">
                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>
 
</mapper>

小结

foreach标签

循环遍历

动态SQL

xml文件里映射

在测试里面调用方法

传入形参集合

遍历集合

拿到集合里的每一个元素

然后拼接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="org.example.mybatis.mapper.UserMapper">
 
    
 
    <!--批量删除员工信息-->
    <!--delete from emp where id  in (2,3)-->
    <delete id="deleteByIds">
        <!--
            collection 遍历的集合
            item 遍历出来的集合
            separator 分隔符
            open 遍历开始前拼接的SQL片段
            close 遍历结束后拼接的SQL片段
            标签体内写要遍历的元素
        -->
        delete from emp where id  in
        <foreach collection="ids" item="id" separator="," open="(" close=")">
            #{id}
        </foreach>
 
    </delete>
 
   
 
</mapper>

mapper接口

package org.example.mybatis.mapper;
 
import org.apache.ibatis.annotations.*;
import org.example.mybatis.pojo.User;
 
import java.time.LocalDate;
import java.util.List;
 
@Mapper//表示当前是Mybatis的一个接口 此时程序运行时框架会自动生成实现类对象(代理对象) 并交给spring的ioc容器
public interface UserMapper {
 
   
 
    //批量删除员工
    public void deleteByIds(List<Integer> ids);
 
}

测试类

package org.example.mybatis;
 
 
import org.example.mybatis.mapper.UserMapper;
import org.example.mybatis.pojo.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
 
import java.sql.*;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
 
@SpringBootTest //springboot整合单元测试的注解
class MybatisApplicationTests {
 
    @Autowired
    //声明接口类型的对象 将此对象注入进来
    private UserMapper userMapper;
    
    @Test
    //批量删除员工3 4 5
    public void testDeleteByIds(){
        List<Integer> ids= Arrays.asList(3,4,5);
 
        userMapper.deleteByIds(ids);
    }
 
 
}

小结

sql include标签

配套使用

看这个配置了两条SQL的映射文件

将代码抽取 抽取一部分SQL片段

然后需要SQL时再引入

sql标签负责抽取SQL

include负责引用片段

组件封装

总结

目录
相关文章
|
1月前
|
XML 前端开发 Java
讲解SSM的xml文件
本文详细介绍了SSM框架中的xml配置文件,包括springMVC.xml和applicationContext.xml,涉及组件扫描、数据源配置、事务管理、MyBatis集成以及Spring MVC的视图解析器配置。
57 1
|
8天前
|
Java Maven
maven项目的pom.xml文件常用标签使用介绍
第四届人文,智慧教育与服务管理国际学术会议(HWESM 2025) 2025 4th International Conference on Humanities, Wisdom Education and Service Management
55 8
|
1月前
|
XML JavaScript Java
java与XML文件的读写
java与XML文件的读写
25 3
|
1月前
|
XML 存储 缓存
C#使用XML文件的详解及示例
C#使用XML文件的详解及示例
88 0
|
SQL 存储
Sql开发技巧
原文:Sql开发技巧 简介 本文主要介绍下述几个技巧: 使用Row_Number分页 事务 根据条件刷选记录的技巧 分页 主要是使用了Row_Number()这个函数。一般如下: declare @PageSize int; declare @StartIndex int; ...
876 0
|
SQL 缓存 数据库
SQL开发技巧(二)
原文:SQL开发技巧(二) 本系列文章旨在收集在开发过程中遇到的一些常用的SQL语句,然后整理归档,本系列文章基于SQLServer系列,且版本为SQLServer2005及以上…… 文章系列目录 SQL开发技巧(一) SQL开发技巧(二) 本文内容简介 这篇文章主要介绍以...
1050 0
|
2月前
|
关系型数据库 MySQL 网络安全
5-10Can't connect to MySQL server on 'sh-cynosl-grp-fcs50xoa.sql.tencentcdb.com' (110)")
5-10Can't connect to MySQL server on 'sh-cynosl-grp-fcs50xoa.sql.tencentcdb.com' (110)")
|
4月前
|
SQL 存储 监控
SQL Server的并行实施如何优化?
【7月更文挑战第23天】SQL Server的并行实施如何优化?
110 13
|
4月前
|
SQL
解锁 SQL Server 2022的时间序列数据功能
【7月更文挑战第14天】要解锁SQL Server 2022的时间序列数据功能,可使用`generate_series`函数生成整数序列,例如:`SELECT value FROM generate_series(1, 10)。此外,`date_bucket`函数能按指定间隔(如周)对日期时间值分组,这些工具结合窗口函数和其他时间日期函数,能高效处理和分析时间序列数据。更多信息请参考官方文档和技术资料。
|
4月前
|
SQL 存储 网络安全
关系数据库SQLserver 安装 SQL Server
【7月更文挑战第26天】
60 6