菜鸟之路Day35一一Mybatis之XML映射与动态SQL

简介: 本文介绍了MyBatis框架中XML映射与动态SQL的使用方法,作者通过实例详细解析了XML映射文件的配置规范,包括namespace、id和resultType的设置。文章还对比了注解与XML映射的优缺点,强调复杂SQL更适合XML方式。在动态SQL部分,重点讲解了`<if>`、`<where>`、`<set>`、`<foreach>`等标签的应用场景,如条件查询、动态更新和批量删除,并通过代码示例展示了其灵活性与实用性。最后,通过`<sql>`和`<include>`实现代码复用,优化维护效率。

菜鸟之路Day35一一Mybatis之XML映射与动态SQL

作者:blue

时间:2025.5.26

0.概述

内容学习自黑马程序员BV1m84y1w7Tb

1.XML映射文件

配置XML映射文件必须遵循以下三个规范

规范:

XML映射文件的名称与Mapper接口名称一致,并且将XML映射文件和Mapper接口放置在相同包下(同包同名)

XML映射文件的namespace属性为Mapper接口全限定名一致

XML映射文件sql语句的id与Mapper接口中的方法名一周,并保持返回类型一致

在src/main/resources/com/bluening/mybatis_demo/mapper配置EmpMapper.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.bluening.mybatis_demo.mapper.EmpMapper">
    <select id="getEmpBy" resultType="com.bluening.mybatis_demo.pojo.Emp">
        select * from tb_emp where name like concat('%',#{name},'%') and
            gender=#{gender} and entry_time between #{begin} and #{end}
            order by update_time desc
    </select>
</mapper>
  • namespace:必须与 Mapper 接口的全限定名一致,确保绑定。
  • id:对应接口中的方法名(getEmpBy)。
  • resultType:指定 SQL 结果映射的目标类(Emp)。

在src/main/java/com/bluening/mybatis_demo/mapper/EmpMapper编写接口

@Mapper
public interface EmpMapper {
   
    //根据条件查询员工信息
    public List<Emp> getEmpBy(String name, int gender, LocalDateTime begin, LocalDateTime end);
}

我们可以安装MyBatisX插件,让我们能够更加轻松的找到对应的映射关系,提高开发效率

image-20250528072247090.png

基于注解VS基于XML映射

使用注解映射简单语句会使代码更加简洁,但对于稍微复杂一点的语句,Java注解不仅力不从心,还会让你本就复杂的SQL语句更加混乱不堪。因此,如果你需要做一些很复杂的操作,最好用XML来映射语句。

选择何种方式来配置映射,以及认为是否应该要统一映射语句定义的形式,完全取决于你和你的团队。换句话说,永远不要拘泥于一种方式,你可以很轻松的在基于注解和 XML的语句映射方式间自由移植和切换。

2.动态SQL

随着用户的输入或者外部条件变化而变化的SQL语句,我们称为动态SQL

2.1if

<if>:用于判断条件是否成立。使用test属性进行条件判断,如果条件为true,则拼接SQL。

<where>:where元素只会在子元素有内容得情况下才插入where子句。而且会自动去除子句的开头的AND或OR

于是我们将XML映射文件中的SQL语句修改成下面这样

    <select id="getEmpBy" resultType="com.bluening.mybatis_demo.pojo.Emp">
        select *
        from tb_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 entry_time between #{begin} and #{end}
            </if>
        </where>
        order by update_time desc
    </select>

接下来我们调整输入的参数,发现SQL语句的建立会动态变化

//输入
List<Emp> emplist =empMapper.getEmpBy("b",1,null,null);

image-20250528080316892.png

案例:完善更新员工功能,修改为动态更新员工数据信息

在我们原始的更新操作中,我们写死更新的字段,导致我们进行部分更新的时候,会导致全体更新,若那个字段为空值,那么原有的值就会被清除掉变为空值,这时我们就可以利用动态SQL来完善更新功能

//更新用户操作
    @Update("update tb_emp set username=#{username},password=#{password},name=#{name},gender=#{gender},image=#{image}," +
            "job=#{job},entry_time=#{entry_time},update_time=#{update_time},dept_id=#{dept_id} " +
            "where id=#{id}")
    public void update(Emp emp);

修改为XML映射动态SQL

<set>:动态地在行首插入SET关键字,并会删掉额外的逗号。(用在update语句中)
    <update id="update">
        update tb_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="entry_time != null">
                entry_time=#{entry_time},
            </if>
            <if test="update_time != null">
                update_time=#{update_time},
            </if>
            <if test="dept_id != null">
                dept_id=#{dept_id}
            </if>
        </set>
        where id=#{id}
    </update>

单元测试

    @Test
    public void testUpdate() {
   
        Emp emp = new Emp();
        emp.setId(16);//指定要修改的对象的id
        emp.setUsername("red");

        empMapper.update(emp);
    }

可见这里的内容被动态修改了
image-20250528085944673.png

2.2foreach

foreach标签主要用于一些批量操作,以下以批量删除员工为例子

批量删除员工原有的SQL语句为

delete from tb_emp where id in (id1,id2,id3,id4)

在EmpMapper中定义接口

//批量删除员工
public void deleteByIds(List<Integer> ids);

建立映射

    <!--批量删除员工-->
    <!--
        collection:遍历的集合,注意与接口中的参数同名
        item:遍历出来的元素
        separator:分隔符
        open:遍历开始前拼接的SQL片段
        close:遍历结束后拼接的SQL片段
    -->
    <delete id="deleteByIds">
        delete from tb_emp where id in
        <foreach collection="ids" item="id" separator="," open="(" close=")">
        #{id}
        </foreach>
    </delete>

单元测试

@Test
public void testDeleteByIds() {
   
    List<Integer> ids = Arrays.asList(1, 2, 3);
    empMapper.deleteByIds(ids);
}

可以看见批量删除的语句被创建出来
image-20250528092830399.png

2.3sql和include的

代码复用性差如果后期表结构有所修改,需要对所有字段进行修改
image-20250528093227021.png

这时我们的想法是抽取相同代码封装,然后再在其具体需要使用的位置引用,这时就可以利用sql标签和include标签
image-20250528093555935.png

目录
相关文章
|
4月前
|
SQL Java 数据库连接
【YashanDB知识库】解决mybatis的mapper文件sql语句结尾加分号";"报错
【YashanDB知识库】解决mybatis的mapper文件sql语句结尾加分号";"报错
|
4月前
|
XML Java 数据库连接
微服务——SpringBoot使用归纳——Spring Boot集成MyBatis——基于 xml 的整合
本教程介绍了基于XML的MyBatis整合方式。首先在`application.yml`中配置XML路径,如`classpath:mapper/*.xml`,然后创建`UserMapper.xml`文件定义SQL映射,包括`resultMap`和查询语句。通过设置`namespace`关联Mapper接口,实现如`getUserByName`的方法。Controller层调用Service完成测试,访问`/getUserByName/{name}`即可返回用户信息。为简化Mapper扫描,推荐在Spring Boot启动类用`@MapperScan`注解指定包路径避免逐个添加`@Mapper`
128 0
|
4月前
|
SQL Java 数据库连接
【YashanDB 知识库】解决 mybatis 的 mapper 文件 sql 语句结尾加分号";"报错
【YashanDB 知识库】解决 mybatis 的 mapper 文件 sql 语句结尾加分号";"报错
|
4月前
|
SQL 缓存 Java
框架源码私享笔记(02)Mybatis核心框架原理 | 一条SQL透析核心组件功能特性
本文详细解构了MyBatis的工作机制,包括解析配置、创建连接、执行SQL、结果封装和关闭连接等步骤。文章还介绍了MyBatis的五大核心功能特性:支持动态SQL、缓存机制(一级和二级缓存)、插件扩展、延迟加载和SQL注解,帮助读者深入了解其高效灵活的设计理念。
|
4月前
|
Java 数据库连接 mybatis
MyBatis篇-映射关系(1-1 1-n n-n)
本文介绍了MyBatis中四种常见关系映射的配置方法,包括一对一、一对多、多对一和多对多。**一对一**通过`resultMap`实现属性与字段的映射;**一对多**以用户-角色为例,使用`&lt;collection&gt;`标签关联集合数据;**多对一**以作者-博客为例,利用`&lt;association&gt;`实现关联;**多对多**则通过引入第三方类(如UserForDept)分别在User和Dept类中添加集合属性,并配置对应的`&lt;collection&gt;`标签完成映射。这些方法解决了复杂数据关系的处理问题,提升了开发效率。
|
2月前
|
Android开发 开发者
Android自定义View之不得不知道的文件attrs.xml(自定义属性)
本文详细介绍了如何通过自定义 `attrs.xml` 文件实现 Android 自定义 View 的属性配置。以一个包含 TextView 和 ImageView 的 DemoView 为例,讲解了如何使用自定义属性动态改变文字内容和控制图片显示隐藏。同时,通过设置布尔值和点击事件,实现了图片状态的切换功能。代码中展示了如何在构造函数中解析自定义属性,并通过方法 `setSetting0n` 和 `setbackeguang` 实现功能逻辑的优化与封装。此示例帮助开发者更好地理解自定义 View 的开发流程与 attrs.xml 的实际应用。
Android自定义View之不得不知道的文件attrs.xml(自定义属性)
|
9月前
|
XML 前端开发 Java
讲解SSM的xml文件
本文详细介绍了SSM框架中的xml配置文件,包括springMVC.xml和applicationContext.xml,涉及组件扫描、数据源配置、事务管理、MyBatis集成以及Spring MVC的视图解析器配置。
200 1
|
11月前
|
XML Java 数据格式
Spring5入门到实战------7、IOC容器-Bean管理XML方式(外部属性文件)
这篇文章是Spring5框架的实战教程,主要介绍了如何在Spring的IOC容器中通过XML配置方式使用外部属性文件来管理Bean,特别是数据库连接池的配置。文章详细讲解了创建属性文件、引入属性文件到Spring配置、以及如何使用属性占位符来引用属性文件中的值。
Spring5入门到实战------7、IOC容器-Bean管理XML方式(外部属性文件)
|
8月前
|
Java Maven
maven项目的pom.xml文件常用标签使用介绍
第四届人文,智慧教育与服务管理国际学术会议(HWESM 2025) 2025 4th International Conference on Humanities, Wisdom Education and Service Management
658 8
|
8月前
|
XML Android开发 数据格式
Eclipse 创建 XML 文件
Eclipse 创建 XML 文件
115 2