后端数据库开发高级之通过在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负责引用片段

组件封装

总结

目录
相关文章
|
9月前
|
关系型数据库 MySQL 数据库
阿里云数据库RDS费用价格:MySQL、SQL Server、PostgreSQL和MariaDB引擎收费标准
阿里云RDS数据库支持MySQL、SQL Server、PostgreSQL、MariaDB,多种引擎优惠上线!MySQL倚天版88元/年,SQL Server 2核4G仅299元/年,PostgreSQL 227元/年起。高可用、可弹性伸缩,安全稳定。详情见官网活动页。
1433 152
|
9月前
|
关系型数据库 MySQL 数据库
阿里云数据库RDS支持MySQL、SQL Server、PostgreSQL和MariaDB引擎
阿里云数据库RDS支持MySQL、SQL Server、PostgreSQL和MariaDB引擎,提供高性价比、稳定安全的云数据库服务,适用于多种行业与业务场景。
1046 156
|
9月前
|
SQL 人工智能 Linux
SQL Server 2025 RC1 发布 - 从本地到云端的 AI 就绪企业数据库
SQL Server 2025 RC1 发布 - 从本地到云端的 AI 就绪企业数据库
718 5
SQL Server 2025 RC1 发布 - 从本地到云端的 AI 就绪企业数据库
|
9月前
|
存储 JSON 数据建模
鸿蒙 HarmonyOS NEXT端云一体化开发-云数据库篇
云数据库采用存储区、对象类型、对象三级结构,支持灵活的数据建模与权限管理,可通过AGC平台或本地项目初始化,实现数据的增删改查及端侧高效调用。
454 1
|
8月前
|
SQL 存储 监控
SQL日志优化策略:提升数据库日志记录效率
通过以上方法结合起来运行调整方案, 可以显著地提升SQL环境下面向各种搜索引擎服务平台所需要满足标准条件下之数据库登记作业流程综合表现; 同时还能确保系统稳健运行并满越用户体验预期目标.
408 6
|
9月前
|
关系型数据库 分布式数据库 数据库
阿里云数据库收费价格:MySQL、PostgreSQL、SQL Server和MariaDB引擎费用整理
阿里云数据库提供多种类型,包括关系型与NoSQL,主流如PolarDB、RDS MySQL/PostgreSQL、Redis等。价格低至21元/月起,支持按需付费与优惠套餐,适用于各类应用场景。
|
9月前
|
SQL Oracle 关系型数据库
Oracle数据库创建表空间和索引的SQL语法示例
以上SQL语法提供了一种标准方式去组织Oracle数据库内部结构,并且通过合理使用可以显著改善查询速度及整体性能。需要注意,在实际应用过程当中应该根据具体业务需求、系统资源状况以及预期目标去合理规划并调整参数设置以达到最佳效果。
599 8
|
10月前
|
SQL 人工智能 Java
用 LangChain4j+Ollama 打造 Text-to-SQL AI Agent,数据库想问就问
本文介绍了如何利用AI技术简化SQL查询操作,让不懂技术的用户也能轻松从数据库中获取信息。通过本地部署PostgreSQL数据库和Ollama模型,结合Java代码,实现将自然语言问题自动转换为SQL查询,并将结果以易懂的方式呈现。整个流程简单直观,适合初学者动手实践,同时也展示了AI在数据查询中的潜力与局限。
1284 8
|
XML 前端开发 Java
讲解SSM的xml文件
本文详细介绍了SSM框架中的xml配置文件,包括springMVC.xml和applicationContext.xml,涉及组件扫描、数据源配置、事务管理、MyBatis集成以及Spring MVC的视图解析器配置。
376 1