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

组件封装

总结

目录
相关文章
|
8天前
|
SQL 数据库
数据库数据恢复—SQL Server数据库报错“错误823”的数据恢复案例
SQL Server附加数据库出现错误823,附加数据库失败。数据库没有备份,无法通过备份恢复数据库。 SQL Server数据库出现823错误的可能原因有:数据库物理页面损坏、数据库物理页面校验值损坏导致无法识别该页面、断电或者文件系统问题导致页面丢失。
52 12
数据库数据恢复—SQL Server数据库报错“错误823”的数据恢复案例
|
10天前
|
Oracle 关系型数据库 数据库
数据库数据恢复—Oracle数据库文件出现坏块的数据恢复案例
打开oracle数据库报错“system01.dbf需要更多的恢复来保持一致性,数据库无法打开”。 数据库没有备份,无法通过备份去恢复数据库。用户方联系北亚企安数据恢复中心并提供Oracle_Home目录中的所有文件,急需恢复zxfg用户下的数据。 出现“system01.dbf需要更多的恢复来保持一致性”这个报错的原因可能是控制文件损坏、数据文件损坏,数据文件与控制文件的SCN不一致等。数据库恢复工程师对数据库文件进一步检测、分析后,发现sysaux01.dbf文件损坏,有坏块。 修复并启动数据库后仍然有许多查询报错,export和data pump工具使用报错。从数据库层面无法修复数据库。
数据库数据恢复—Oracle数据库文件出现坏块的数据恢复案例
|
12天前
|
SQL 监控 关系型数据库
MySQL数据库中如何检查一条SQL语句是否被回滚
检查MySQL中的SQL语句是否被回滚需要综合使用日志分析、事务状态监控和事务控制语句。理解和应用这些工具和命令,可以有效地管理和验证数据库事务的执行情况,确保数据的一致性和系统的稳定性。此外,熟悉事务的ACID属性和正确设置事务隔离级别对于预防数据问题和解决事务冲突同样重要。
27 2
|
20天前
|
存储 NoSQL 关系型数据库
可以存储文件的数据库有哪些?
可以存储文件的数据库有哪些?
18 6
|
16天前
|
存储 NoSQL 关系型数据库
可以存储文件的数据库有哪些?
可以存储文件的数据库有哪些?
127 0
|
24天前
|
SQL 安全 数据库
基于SQL Server事务日志的数据库恢复技术及实战代码详解
基于事务日志的数据库恢复技术是SQL Server中一个非常强大的功能,它能够帮助数据库管理员在数据丢失或损坏的情况下,有效地恢复数据。通过定期备份数据库和事务日志,并在需要时按照正确的步骤恢复,可以最大限度地减少数据丢失的风险。需要注意的是,恢复数据是一个需要谨慎操作的过程,建议在执行恢复操作之前,详细了解相关的操作步骤和注意事项,以确保数据的安全和完整。
56 0
|
28天前
|
前端开发 C# 设计模式
“深度剖析WPF开发中的设计模式应用:以MVVM为核心,手把手教你重构代码结构,实现软件工程的最佳实践与高效协作”
【8月更文挑战第31天】设计模式是在软件工程中解决常见问题的成熟方案。在WPF开发中,合理应用如MVC、MVVM及工厂模式等能显著提升代码质量和可维护性。本文通过具体案例,详细解析了这些模式的实际应用,特别是MVVM模式如何通过分离UI逻辑与业务逻辑,实现视图与模型的松耦合,从而优化代码结构并提高开发效率。通过示例代码展示了从模型定义、视图模型管理到视图展示的全过程,帮助读者更好地理解并应用这些模式。
52 0
|
28天前
|
SQL 数据处理 数据库
|
28天前
|
Java 数据库连接 数据库
告别繁琐 SQL!Hibernate 入门指南带你轻松玩转 ORM,解锁高效数据库操作新姿势
【8月更文挑战第31天】Hibernate 是一款流行的 Java 持久层框架,简化了对象关系映射(ORM)过程,使开发者能以面向对象的方式进行数据持久化操作而无需直接编写 SQL 语句。本文提供 Hibernate 入门指南,介绍核心概念及示例代码,涵盖依赖引入、配置文件设置、实体类定义、工具类构建及基本 CRUD 操作。通过学习,你将掌握使用 Hibernate 简化数据持久化的技巧,为实际项目应用打下基础。
57 0
|
28天前
|
SQL 存储 监控