菜鸟之路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

目录
相关文章
|
6月前
|
SQL Java 数据库连接
【YashanDB知识库】解决mybatis的mapper文件sql语句结尾加分号";"报错
【YashanDB知识库】解决mybatis的mapper文件sql语句结尾加分号";"报错
|
5月前
|
SQL Java 数据库连接
MyBatis动态SQL字符串空值判断,这个细节99%的程序员都踩过坑!
本文深入探讨了MyBatis动态SQL中字符串参数判空的常见问题。通过具体案例分析,对比了`name != null and name != &#39;&#39;`与`name != null and name != &#39; &#39;`两种写法的差异,指出后者可能引发逻辑混乱。为避免此类问题,建议在后端对参数进行预处理(如trim去空格),简化MyBatis判断逻辑,提升代码健壮性与可维护性。细节决定成败,严谨处理参数判空是写出高质量代码的关键。
635 0
|
6月前
|
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`
266 0
|
6月前
|
SQL Java 数据库连接
【YashanDB 知识库】解决 mybatis 的 mapper 文件 sql 语句结尾加分号";"报错
【YashanDB 知识库】解决 mybatis 的 mapper 文件 sql 语句结尾加分号";"报错
|
3月前
|
Java 数据库连接 数据库
Spring boot 使用mybatis generator 自动生成代码插件
本文介绍了在Spring Boot项目中使用MyBatis Generator插件自动生成代码的详细步骤。首先创建一个新的Spring Boot项目,接着引入MyBatis Generator插件并配置`pom.xml`文件。然后删除默认的`application.properties`文件,创建`application.yml`进行相关配置,如设置Mapper路径和实体类包名。重点在于配置`generatorConfig.xml`文件,包括数据库驱动、连接信息、生成模型、映射文件及DAO的包名和位置。最后通过IDE配置运行插件生成代码,并在主类添加`@MapperScan`注解完成整合
555 1
Spring boot 使用mybatis generator 自动生成代码插件
|
6月前
|
XML Java 数据库连接
微服务——SpringBoot使用归纳——Spring Boot集成MyBatis——基于注解的整合
本文介绍了Spring Boot集成MyBatis的两种方式:基于XML和注解的形式。重点讲解了注解方式,包括@Select、@Insert、@Update、@Delete等常用注解的使用方法,以及多参数时@Param注解的应用。同时,针对字段映射不一致的问题,提供了@Results和@ResultMap的解决方案。文章还提到实际项目中常结合XML与注解的优点,灵活使用两者以提高开发效率,并附带课程源码供下载学习。
493 0
|
8月前
|
前端开发 Java 数据库连接
Java后端开发-使用springboot进行Mybatis连接数据库步骤
本文介绍了使用Java和IDEA进行数据库操作的详细步骤,涵盖从数据库准备到测试类编写及运行的全过程。主要内容包括: 1. **数据库准备**:创建数据库和表。 2. **查询数据库**:验证数据库是否可用。 3. **IDEA代码配置**:构建实体类并配置数据库连接。 4. **测试类编写**:编写并运行测试类以确保一切正常。
308 2
|
11月前
|
Java 数据库连接 Maven
mybatis使用一:springboot整合mybatis、mybatis generator,使用逆向工程生成java代码。
这篇文章介绍了如何在Spring Boot项目中整合MyBatis和MyBatis Generator,使用逆向工程来自动生成Java代码,包括实体类、Mapper文件和Example文件,以提高开发效率。
420 2
mybatis使用一:springboot整合mybatis、mybatis generator,使用逆向工程生成java代码。
|
11月前
|
SQL JSON Java
mybatis使用三:springboot整合mybatis,使用PageHelper 进行分页操作,并整合swagger2。使用正规的开发模式:定义统一的数据返回格式和请求模块
这篇文章介绍了如何在Spring Boot项目中整合MyBatis和PageHelper进行分页操作,并且集成Swagger2来生成API文档,同时定义了统一的数据返回格式和请求模块。
324 1
mybatis使用三:springboot整合mybatis,使用PageHelper 进行分页操作,并整合swagger2。使用正规的开发模式:定义统一的数据返回格式和请求模块
|
11月前
|
前端开发 Java Apache
Springboot整合shiro,带你学会shiro,入门级别教程,由浅入深,完整代码案例,各位项目想加这个模块的人也可以看这个,又或者不会mybatis-plus的也可以看这个
本文详细讲解了如何整合Apache Shiro与Spring Boot项目,包括数据库准备、项目配置、实体类、Mapper、Service、Controller的创建和配置,以及Shiro的配置和使用。
2405 1
Springboot整合shiro,带你学会shiro,入门级别教程,由浅入深,完整代码案例,各位项目想加这个模块的人也可以看这个,又或者不会mybatis-plus的也可以看这个