[笔记] MyBatis-Plus XML 配置详解:从基础到高级,全面提升开发效率

news2025/1/15 5:03:32

文章目录

  • 一. 基础标签
    • 1. select 标签
    • 2. insert 标签
    • 3. update 标签
    • 4. delete 标签
  • 二. 动态 SQL 标签
    • 1. if 标签
    • 2. choose-when-otherwise 标签
    • 3. where 标签
    • 4. set 标签
    • 5. trim 标签
    • 6. foreach 标签
  • 三. 高级映射
    • 1. resultMap 标签
    • 2. sql 标签
  • 四. 特殊功能
    • 1. bind 标签
    • 2. 特殊字符:CDATA 区段(关联 XML 实体)
    • 3. 特殊字符:XML 实体(关联 CDATA 区段)
  • 五. 实用场景示例
    • 1. 动态表关联
    • 2. 批量操作优化
  • 六. 最佳实践
    • 1. 性能优化
    • 2. 安全性
    • 3. 可维护性
  • 七. 注意事项


MyBatis-Plus 是一个 MyBatis 的增强工具,旨在简化开发过程,提供更便捷的数据库操作方式。在 MyBatis-Plus 中,XML 配置文件扮演着重要的角色,它允许开发者定义 SQL 语句、映射结果集以及配置各种数据库操作。本文将详细介绍 MyBatis-Plus XML 配置文件中的各种标签和功能,从基础的查询、插入、更新、删除操作,到高级的动态 SQL、结果映射和批量操作,帮助你全面掌握 MyBatis-Plus 的 XML 配置技巧,提升开发效率。(主要就是因为 mybatis-plus 封装的太好了,能不写sql就不写,到写的时候都忘记了…)

MyBatis-Plus 官网 : Mybatis-Plus
MyBatis 官网 : Mybatis中文官网
SQL 优化 :[笔记] SQL数据库优化实战 : SQL 全面优化


一. 基础标签

1. select 标签

<select id="getById" resultType="User" parameterType="long">
    SELECT * FROM user WHERE id = #{id}
</select>

用于查询操作,最基本的查询标签。

  • id: 对应 Mapper 接口中的方法名。
  • resultType: 返回的结果类型。
  • parameterType: 参数类型(可选)。

2. insert 标签

<insert id="insert" parameterType="User" useGeneratedKeys="true" keyProperty="id">
    INSERT INTO user (username, age) VALUES (#{username}, #{age})
</insert>

用于插入操作。

  • useGeneratedKeys: 是否使用自增主键。
  • keyProperty: 自增主键对应的属性名。

3. update 标签

<update id="update" parameterType="User">
    UPDATE user SET username = #{username} WHERE id = #{id}
</update>

用于更新操作。

  • parameterType: 参数类型。

4. delete 标签

<delete id="deleteById" parameterType="long">
    DELETE FROM user WHERE id = #{id}
</delete>

用于删除操作。

  • parameterType: 参数类型。

二. 动态 SQL 标签

1. if 标签

<if test="username != null and username != ''">
    AND username LIKE CONCAT('%', #{username}, '%')
</if>

条件判断,当 test 属性中的条件成立时,才会将其包含的 SQL 片段拼接到最终的 SQL 中。

  • test: 判断条件,支持 OGNL 表达式

2. choose-when-otherwise 标签

<choose>
    <when test="status != null">
        AND status = #{status}
    </when>
    <when test="type != null">
        AND type = #{type}
    </when>
    <otherwise>
        AND create_time > SYSDATE
    </otherwise>
</choose>

类似 Java 中的 switch 语句,只会执行一个条件。

3. where 标签

<where>
    <if test="username != null">
        AND username = #{username}
    </if>
    <if test="age != null">
        AND age >= #{age}
    </if>
</where>

自动处理 WHERE 子句,会自动去除多余的 ANDOR

4. set 标签

<update id="updateUser">
    UPDATE user
    <set>
        <if test="username != null">username = #{username},</if>
        <if test="age != null">age = #{age},</if>
    </set>
    WHERE id = #{id}
</update>

用在 UPDATE 语句中,自动处理 SET 关键字和逗号。

5. trim 标签

<trim prefix="WHERE" prefixOverrides="AND|OR" suffix=")" suffixOverrides=",">
    <if test="username != null">
        AND username = #{username},
    </if>
</trim>

更灵活的前缀/后缀处理。

  • prefix: 给整个语句增加前缀。
  • prefixOverrides: 去除整个语句前面的关键字或字符。
  • suffix: 给整个语句增加后缀。
  • suffixOverrides: 去除整个语句后面的关键字或字符。
  • 运行结果 : WHERE username = #{username}

6. foreach 标签

<foreach collection="list" item="item" index="index" open="(" separator="," close=")">
    #{item}
</foreach>

循环遍历集合或数组。

  • collection: 要遍历的集合或数组(listarraymap等)。
  • item: 当前遍历的元素。
  • index: 当前遍历的索引。
  • open: 开始字符。
  • separator: 分隔符。
  • close: 结束字符。

三. 高级映射

1. resultMap 标签

<resultMap id="UserResultMap" type="User">
    <!-- 主键映射 -->
    <id property="id" column="user_id"/>
    
    <!-- 普通属性映射 -->
    <result property="username" column="user_name"/>
    
    <!-- 一对一关系 -->
    <association property="profile" javaType="UserProfile">
        <id property="id" column="profile_id"/>
        <result property="address" column="address"/>
    </association>
    
    <!-- 一对多关系 -->
    <collection property="roles" ofType="Role">
        <id property="id" column="role_id"/>
        <result property="roleName" column="role_name"/>
    </collection>
</resultMap>

自定义结果映射关系。

  • <resultMap>标签
    • id="UserResultMap": 定义了这个 <resultMap> 的唯一标识符,以便在其他地方引用它。
    • type="User": 指定了这个 <resultMap> 所映射的目标类型,这里是 User 类。

  • 主键映射
    • <id property="id" column="user_id"/>: 映射数据库表中的 user_id 列到 User 对象的 id 属性上。<id> 标签通常用于主键映射,有助于提高 MyBatis 在处理关联关系时的性能。

  • 普通属性映射
    • <result property="username" column="user_name"/>: 将数据库表中的 user_name 列映射到 User 对象的 username 属性上。<result> 标签用于普通属性的映射。

  • 一对一关系 (<association>)
    • property="profile" javaType="UserProfile": 表示 User 对象与 UserProfile 对象之间存在一对一的关系,并且将查询结果映射到 User 对象的 profile 属性上。
      • <id property="id" column="profile_id"/>: 映射 UserProfile 对象的主键。
      • <result property="address" column="address"/>: 映射 UserProfile 对象的 address 属性。

  • 一对多关系 (<collection>)
    • property="roles" ofType="Role": 表示 User 对象与多个 Role 对象之间存在一对多的关系,并且将查询结果映射到 User 对象的 roles 属性上。
      • <id property="id" column="role_id"/>: 映射每个 Role 对象的主键。
      • <result property="roleName" column="role_name"/>: 映射每个 Role 对象的 roleName 属性。

2. sql 标签

<!-- 定义 SQL 片段 -->
<sql id="Base_Column_List">
    id, username, age, email, create_time
</sql>

<!-- 使用 SQL 片段 -->
<select id="selectById">
    SELECT <include refid="Base_Column_List"/> FROM user
</select>

定义可重用的 SQL 片段。


四. 特殊功能

1. bind 标签

<select id="selectByName">
    <bind name="pattern" value="'%' + name + '%'"/>
    SELECT * FROM user WHERE username LIKE #{pattern}
</select>

创建一个变量并绑定到上下文中。

2. 特殊字符:CDATA 区段(关联 XML 实体)

<select id="getUsers">
    SELECT * FROM user
    WHERE age <![CDATA[ >= ]]> #{minAge}
</select>

处理特殊字符。

3. 特殊字符:XML 实体(关联 CDATA 区段)

  • 预定义的 XML 实体
<select id="getUsers">
    SELECT * FROM user
    WHERE age &gt;= #{minAge}
</select>

预定义的 XML 实体

  • < 对应 &lt;
  • > 对应 &gt;
  • & 对应 &amp;
  • " 对应 &quot;
  • ' 对应 &apos;
  • 自定义实体
<!-- DOCTYPE声明 -->
<!DOCTYPE example [
    <!ENTITY myEntity "This is a custom entity">
]>

<!-- 使用 -->
<example>
    Here is the custom entity: &myEntity;
</example>

<!-- 结果 -->
<example>
    Here is the custom entity: This is a custom entity
</example>

自定义实体允许你在XML文档中定义一些简短的替代符号,这些符号可以在文档的不同部分引用。

代码解释

  • <!DOCTYPE example [...] >: 这是一个DOCTYPE声明,用于定义当前文档的类型和结构。在这个例子中,example是根元素名称,方括号[]内包含了自定义实体的定义。
  • <!ENTITY myEntity "This is a custom entity">: 定义了一个名为myEntity的自定义实体。myEntity是一个标识符,"This is a custom entity"是这个实体的实际值。在文档的其他地方,你可以通过&myEntity;来引用这个实体。
  • <example>: 根元素,包含文档的主要内容。
  • Here is the custom entity: &myEntity;: 在这个元素的内容中,使用了之前定义的自定义实体&myEntity;。当解析器读取到这个标记时,会自动将其替换为实体的实际值"This is a custom entity"

渲染结果

当你解析这个XML文档时,解析器会将&myEntity;替换为其定义的值。最终的结果将是:

<example>
    Here is the custom entity: This is a custom entity
</example>

五. 实用场景示例

1. 动态表关联

<select id="getUserDetails" resultMap="UserDetailMap">
    SELECT u.* 
    FROM user u
    <!-- 动态关联用户资料表 -->
    <if test="includeProfile">
        LEFT JOIN user_profile up ON u.id = up.user_id
    </if>
    <!-- 动态关联角色表 -->
    <if test="includeRoles">
        LEFT JOIN user_role ur ON u.id = ur.user_id
        LEFT JOIN role r ON ur.role_id = r.id
    </if>
    WHERE u.id = #{userId}
</select>

根据条件决定是否关联其他表。

动态地从多个表中获取用户详细信息。

代码解析

  • <select id="getUserDetails" resultMap="UserDetailMap">: 定义了这个查询的唯一标识符,可以在Java代码中通过这个ID来调用该查询,并指定了结果映射(resultMap)。

  • SELECT u.* FROM user u: 选择了user表中的所有列,并给这个表起了一个别名u

  • 动态关联用户资料表:

    <if test="includeProfile">
        LEFT JOIN user_profile up ON u.id = up.user_id
    </if>
    
    • 检查传入的参数includeProfile是否为true。如果为true,则执行内部的SQL片段。
  • 动态关联角色表:

    <if test="includeRoles">
        LEFT JOIN user_role ur ON u.id = ur.user_id
        LEFT JOIN role r ON ur.role_id = r.id
    </if>
    
    • 检查传入的参数includeRoles是否为true。如果为true,则执行内部的SQL片段。
  • WHERE u.id = #{userId}: 这条语句用于过滤结果,只返回指定用户ID的数据。


调用
传参:

  • includeProfile = true
  • includeRoles = true
  • userId = 1

生成的SQL:

SELECT u.* 
FROM user u
LEFT JOIN user_profile up ON u.id = up.user_id
LEFT JOIN user_role ur ON u.id = ur.user_id
LEFT JOIN role r ON ur.role_id = r.id
WHERE u.id  

2. 批量操作优化

<!-- MySQL批量更新 -->
<update id="batchUpdate">
    UPDATE user
    <trim prefix="SET" suffixOverrides=",">
        <trim prefix="username = CASE" suffix="END,">
            <foreach collection="list" item="item">
                WHEN id = #{item.id} THEN #{item.username}
            </foreach>
        </trim>
    </trim>
    WHERE id IN
    <foreach collection="list" item="item" open="(" separator="," close=")">
        #{item.id}
    </foreach>
</update>

适用于大量数据的批量操作。

批量更新用户表中的数据。

代码解析

  • <update id="batchUpdate">: 定义了这个更新操作的唯一标识符,可以在Java代码中通过这个ID来调用该更新操作。

  • UPDATE user: 指定了要更新的表名,这里是user表。

  • 第一个 <trim> 标签:

    <trim prefix="SET" suffixOverrides=",">
        ...
    </trim>
    
    • prefix="SET": 在生成的SQL语句前添加SET关键字。
    • suffixOverrides=",": 自动移除生成的SQL语句末尾多余的逗号。
  • 第二个 <trim> 标签:

    <trim prefix="username = CASE" suffix="END,">
        ...
    </trim>
    
    • prefix="username = CASE": 在生成的SQL语句前添加username = CASE
    • suffix="END,": 在生成的SQL语句后添加END,
  • 嵌套的 <foreach> 标签:

    <foreach collection="list" item="item">
        WHEN id = #{item.id} THEN #{item.username}
    </foreach>
    
    • collection="list": 指定要遍历的集合,这里假设传入的参数是一个包含多个用户的列表。
    • item="item": 定义当前遍历项的变量名,这里是item
  • WHERE id IN ...:

    WHERE id IN
    <foreach collection="list" item="item" open="(" separator="," close=")">
        #{item.id}
    </foreach>
    
    • 这部分使用另一个<foreach>标签来生成WHERE id IN (...)子句。

整体效果

假设你传入的参数是一个包含两个用户的列表,每个用户都有一个id和一个新的username值:

List<User> userList = new ArrayList<>();
userList.add(new User(1, "newUsername1"));
userList.add(new User(2, "newUsername2"));

生成的最终SQL语句将会是:

UPDATE user 
SET username = CASE 
    WHEN id = 1 THEN 'newUsername1' 
    WHEN id = 2 THEN 'newUsername2' 
END 
WHERE id IN (1, 2);

六. 最佳实践

1. 性能优化

  • 避免使用 SELECT *,只查询需要的字段。
  • 合理使用索引。
  • 大量数据操作时使用批量处理。
  • 适当使用缓存。

2. 安全性

  • 使用 #{} 而不是 ${} 来防止 SQL 注入。
  • 参数校验。
  • 敏感数据加密。

3. 可维护性

  • 使用统一的命名规范
  • 添加适当的注释
  • 复杂 SQL 进行模块化处理
  • 保持代码整洁和可读性

七. 注意事项

  1. #{}${} 的区别:
    • #{} 会进行预编译,防止 SQL 注入。
    • ${} 直接替换,有 SQL 注入风险。
  2. 动态 SQL 的顺序很重要,要注意逻辑的先后顺序。
  3. 批量操作时注意数据库的性能限制。
  4. 复杂查询建议使用 resultMap 而不是 resultType
  5. 对于大量重复的 SQL 片段,建议使用 sql 标签复用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2276812.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

USB 驱动开发 --- Gadget 驱动框架梳理(一)

本文由 Linux 内核文档翻译与总结而来&#xff0c;个人学习笔记仅供参考。 Gadget 框架 在 USB 协议交互过程中&#xff0c;角色定义&#xff1a; the device driver is the master (or “client driver”) Linux 内核中称为 HCD(Host Controller Driver)&#xff0c;负责与 …

字符串算法篇——字里乾坤,算法织梦,解构字符串的艺术(下)

文章目录 前言第一章&#xff1a;最长公共前缀1.1 题目链接&#xff1a;https://leetcode.cn/problems/longest-common-prefix/description/1.2 题目分析&#xff1a;1.3 思路讲解&#xff1a;1.4 代码实现&#xff1a; 第二章&#xff1a;最长回文子串2.1 题目链接&#xff1a…

计算机网络 笔记 数据链路层3(局域网,广域网,网桥,交换机)

局域网: LAN:在某一区域内由多台计算机互联成的计算机组&#xff0c;使用广播信道 特点&#xff1a; 覆盖范围有限&#xff1a;通常局限在几千米范围内&#xff0c;比如一栋办公楼、一个校园或一个工厂等相对较小的地理区域。 数据传输速率高&#xff1a;一般能达到 10Mbps…

istio-proxy oom问题排查步骤

1. 查看cluster数量 cluster数量太多会导致istio-proxy占用比较大的内存&#xff0c;此时需检查是否dr资源的host设置有配置为* 2. 查看链路数据采样率 若采样率设置过高&#xff0c;在压测时需要很大的内存来维护链路数据。可以调低采样率或增大istio-proxy内存。 检查iop中…

fast-crud select下拉框 实现多选功能及下拉框数据动态获取(通过接口获取)

教程 fast-crud select示例配置需求:需求比较复杂 1. 下拉框选项需要通过后端接口获取 2. 实现多选功能 由于这个前端框架使用逻辑比较复杂我也是第一次使用,所以只记录核心问题 环境:vue3,typescript,fast-crud ,elementPlus 效果 代码 // crud.tsx文件(/.ts也行 js应…

Apache JMeter 压力测试使用说明

文章目录 一、 安装步骤步骤一 下载相关的包步骤二 安装 Jmeter步骤三 设置 Jmeter 工具语言类型为中文 二、使用工具2.1 创建测试任务步骤一 创建线程组步骤二 创建 HTTP 请求 2.2 配置 HTTP 默认参数添加 HTTP消息头管理器HTTP请求默认值 2.3 添加 查看结果监听器2.4 查看结果…

计算机网络 (40)域名系统DNS

前言 计算机网络域名系统DNS&#xff08;Domain Name System&#xff09;是互联网的基础技术之一&#xff0c;它负责将人类可读的域名转换为计算机用来通信的数字IP地址。 一、基本概念 DNS的主要目的是将域名解析或翻译为IP地址&#xff0c;使得用户可以通过简单易记的域名来访…

本地服务器Docker搭建个人云音乐平台Splayer并实现远程访问告别烦人广告

前言 大家好&#xff01;今天我要给大家分享的是如何在Ubuntu上用Docker快速搭建高颜值无广告的某抑云音乐播放器Splayer的详细流程&#xff0c;并且结合cpolar内网穿透工具实现远程访问。如果你是音乐爱好者&#xff0c;经常需要在外办公或旅行&#xff0c;这个教程绝对能让你…

黑马linux入门笔记(01)初始Linux Linux基础命令 用户和权限 实用操作

B站 黑马程序员 的视频 BV1n84y1i7td 黑马程序员新版Linux零基础快速入门到精通&#xff0c;全涵盖linux系统知识、常用软件环境部署、Shell脚本、云平台实践、大数据集群项目实战等 增强自控力 冥想慢呼吸绿色锻炼充分休息减少决策次数优先做重要的事情(早晨)融入强自控群控…

小程序组件 —— 31 事件系统 - 事件绑定和事件对象

小程序中绑定事件和网页开发中绑定事件几乎一致&#xff0c;只不过在小程序不能通过 on 的方式绑定事件&#xff0c;也没有 click 等事件&#xff0c;小程序中绑定事件使用 bind 方法&#xff0c;click 事件也需要使用 tap 事件来进行代替&#xff0c;绑定事件的方式有两种&…

UE5 使用内置组件进行网格切割

UE引擎非常强大&#xff0c;直接内置了网格切割功能并封装为蓝图节点&#xff0c;这项功能在UE4中就存在&#xff0c;并且无需使用Chaos等模块。那么就来学习下如何使用内置组件实现网格切割。 1.配置测试用StaticMesh 对于被切割的模型&#xff0c;需要配置一些参数。以UE5…

ue5 1.平A,两段连击蒙太奇。鼠标点一下,就放2段动画。2,动画混合即融合,边跑边挥剑,3,动画通知,动画到某一帧,把控制权交给蓝图。就执行蓝图节点

新建文件夹 创建一个蒙太奇MA_Melee 找到c_slow 调节一下速度 把D_slow拖上去 中间加一个片段 哎呀呀&#xff0c;写错了&#xff0c;我想写2 把这个标记拖过来&#xff0c;点击默认default 弄第二个片段 就会自己变成这个样子 把2这个标记拖到中间 鼠标左键&a…

《机器学习》之K-means聚类

目录 一、简介 二、K-means聚类实现步骤 1、初始化数据点、确定K值 2、通过距离分配数据点 3、更新簇中心 4、 迭代更新 三、聚类效果评价方式 1、轮廓系数的定义 2、整体轮廓系数 3、使用场景 4、优点 5、缺点 6、代码实现方法 四、K-means聚类代码实现 1、API接…

Wireshark抓包教程(2024最新版个人笔记)

改内容是个人的学习笔记 Wireshark抓包教程&#xff08;2024最新版&#xff09;_哔哩哔哩_bilibili 该课程笔记1-16 wireshark基础 什么是抓包工具&#xff1a;用来抓取数据包的一个软件 wireshark的功能&#xff1a;用来网络故障排查&#xff1b;用来学习网络技术 wireshark下…

Web开发(一)HTML5

Web开发&#xff08;一&#xff09;HTML5 写在前面 参考黑马程序员前端Web教程做的笔记&#xff0c;主要是想后面自己搭建网页玩。 这部分是前端HTML5CSS3移动web视频教程的HTML5部分。主要涉及到HTML的基础语法。 HTML基础 标签定义 HTML定义 HTML(HyperText Markup Lan…

RabbitMQ 的工作模式

目录 工作模式 Simple&#xff08;简单模式&#xff09; Work Queue&#xff08;工作队列&#xff09; Publish/Subscribe&#xff08;发布/订阅&#xff09; Exchange&#xff08;交换机&#xff09; Routing&#xff08;路由模式&#xff09; Topics&#xff08;通配…

备战蓝桥杯:树的存储与遍历(dfs和bfs)

树的概念 树的逻辑结构是树形结构&#xff0c;和我们之前的线性结构又不太一样了&#xff0c;是一种一对多的关系 树的结点分为根节点&#xff0c;叶子结点&#xff08;没有分支的结点&#xff09; 以及分支结点 从上往下看&#xff0c;每个结点都有0个或多个后继 从下往上…

超大规模分类(三):KNN softmax

传统的分类损失计算输入数据和每个类别中心的距离&#xff0c;来优化模型的训练。KNN softmax通过选择和输入数据最相关的top-K个类别&#xff0c;仅计算输入数据和top-K个类别中心的距离&#xff0c;以减小计算量。 KNN softmax首次诞生于达摩院机器智能技术实验室发表的SIGKD…

ubuntu官方软件包网站 字体设置

在https://ubuntu.pkgs.org/22.04/ubuntu-universe-amd64/xl2tpd_1.3.16-1_amd64.deb.html搜索找到需要的软件后&#xff0c;点击&#xff0c;下滑&#xff0c; 即可在Links和Download找到相关链接&#xff0c;下载即可&#xff0c; 但是找不到ros的安装包&#xff0c; 字体设…

项目实战——使用python脚本完成指定OTA或者其他功能的自动化断电上电测试

前言 在嵌入式设备的OTA场景测试和其他断电上电测试过程中&#xff0c;有的场景发生在夜晚或者随时可能发生&#xff0c;这个时候不可能24h人工盯着&#xff0c;需要自动化抓取串口日志处罚断电上电操作。 下面的python脚本可以实现自动抓取串口指定关键词&#xff0c;然后触发…