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

打印 上一主题 下一主题

主题 800|帖子 800|积分 2400


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 标签

  1. <select id="getById" resultType="User" parameterType="long">
  2.     SELECT * FROM user WHERE id = #{id}
  3. </select>
复制代码
  用于查询操作,最根本的查询标签。
  

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

  1. <insert id="insert" parameterType="User" useGeneratedKeys="true" keyProperty="id">
  2.     INSERT INTO user (username, age) VALUES (#{username}, #{age})
  3. </insert>
复制代码
  用于插入操作。
  

  • useGeneratedKeys: 是否使用自增主键。
  • keyProperty: 自增主键对应的属性名。
  3. update 标签

  1. <update id="update" parameterType="User">
  2.     UPDATE user SET username = #{username} WHERE id = #{id}
  3. </update>
复制代码
  用于更新操作。
  

  • parameterType: 参数类型。
  4. delete 标签

  1. <delete id="deleteById" parameterType="long">
  2.     DELETE FROM user WHERE id = #{id}
  3. </delete>
复制代码
  用于删除操作。
  

  • parameterType: 参数类型。
  
二. 动态 SQL 标签

1. if 标签

  1. <if test="username != null and username != ''">
  2.     AND username LIKE CONCAT('%', #{username}, '%')
  3. </if>
复制代码
  条件判断,当 test 属性中的条件建立时,才会将其包罗的 SQL 片断拼接到终极的 SQL 中。
  

  • test: 判断条件,支持 OGNL 表达式
  2. choose-when-otherwise 标签

  1. <choose>
  2.     <when test="status != null">
  3.         AND status = #{status}
  4.     </when>
  5.     <when test="type != null">
  6.         AND type = #{type}
  7.     </when>
  8.     <otherwise>
  9.         AND create_time > SYSDATE
  10.     </otherwise>
  11. </choose>
复制代码
  雷同 Java 中的 switch 语句,只会执行一个条件。
  3. where 标签

  1. <where>
  2.     <if test="username != null">
  3.         AND username = #{username}
  4.     </if>
  5.     <if test="age != null">
  6.         AND age >= #{age}
  7.     </if>
  8. </where>
复制代码
  主动处理 WHERE 子句,会主动去除多余的 AND 或 OR。
  4. set 标签

  1. <update id="updateUser">
  2.     UPDATE user
  3.     <set>
  4.         <if test="username != null">username = #{username},</if>
  5.         <if test="age != null">age = #{age},</if>
  6.     </set>
  7.     WHERE id = #{id}
  8. </update>
复制代码
  用在 UPDATE 语句中,主动处理 SET 关键字和逗号。
  5. trim 标签

  1. <trim prefix="WHERE" prefixOverrides="AND|OR" suffix=")" suffixOverrides=",">
  2.     <if test="username != null">
  3.         AND username = #{username},
  4.     </if>
  5. </trim>
复制代码
  更灵活的前缀/后缀处理。
  

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

  1. <foreach collection="list" item="item" index="index" open="(" separator="," close=")">
  2.     #{item}
  3. </foreach>
复制代码
  循环遍历集合或数组。
  

  • collection: 要遍历的集合或数组(list、array、map等)。
  • item: 当前遍历的元素。
  • index: 当前遍历的索引。
  • open: 开始字符。
  • separator: 分隔符。
  • close: 结束字符。
  
三. 高级映射

1. resultMap 标签

  1. <resultMap id="UserResultMap" type="User">
  2.     <!-- 主键映射 -->
  3.     <id property="id" column="user_id"/>
  4.    
  5.     <!-- 普通属性映射 -->
  6.     <result property="username" column="user_name"/>
  7.    
  8.     <!-- 一对一关系 -->
  9.     <association property="profile" javaType="UserProfile">
  10.         <id property="id" column="profile_id"/>
  11.         <result property="address" column="address"/>
  12.     </association>
  13.    
  14.     <!-- 一对多关系 -->
  15.     <collection property="roles" ofType="Role">
  16.         <id property="id" column="role_id"/>
  17.         <result property="roleName" column="role_name"/>
  18.     </collection>
  19. </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 标签

  1. <!-- 定义 SQL 片段 -->
  2. <sql id="Base_Column_List">
  3.     id, username, age, email, create_time
  4. </sql>
  5. <!-- 使用 SQL 片段 -->
  6. <select id="selectById">
  7.     SELECT <include refid="Base_Column_List"/> FROM user
  8. </select>
复制代码
  定义可重用的 SQL 片断。
  
四. 特殊功能

1. bind 标签

  1. <select id="selectByName">
  2.     <bind name="pattern" value="'%' + name + '%'"/>
  3.     SELECT * FROM user WHERE username LIKE #{pattern}
  4. </select>
复制代码
  创建一个变量并绑定到上下文中。
  2. 特殊字符:CDATA 区段(关联 XML 实体)

  1. <select id="getUsers">
  2.     SELECT * FROM user
  3.     WHERE age <![CDATA[ >= ]]> #{minAge}
  4. </select>
复制代码
  处理特殊字符。
  3. 特殊字符:XML 实体(关联 CDATA 区段)



  • 预定义的 XML 实体
  1. <select id="getUsers">
  2.     SELECT * FROM user
  3.     WHERE age &gt;= #{minAge}
  4. </select>
复制代码
  预定义的 XML 实体
  

  • < 对应 <。
  • > 对应 >。
  • & 对应 &。
  • " 对应 "。
  • ' 对应 &apos;。
  

  • 自定义实体
  1. <!-- DOCTYPE声明 -->
  2. <!DOCTYPE example [
  3.     <!ENTITY myEntity "This is a custom entity">
  4. ]>
  5. <!-- 使用 -->
  6. <example>
  7.     Here is the custom entity: &myEntity;
  8. </example>
  9. <!-- 结果 -->
  10. <example>
  11.     Here is the custom entity: This is a custom entity
  12. </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;更换为其定义的值。终极的结果将是:
  1. <example>
  2.     Here is the custom entity: This is a custom entity
  3. </example>
复制代码

五. 实用场景示例

1. 动态表关联

  1. <select id="getUserDetails" resultMap="UserDetailMap">
  2.     SELECT u.*
  3.     FROM user u
  4.     <!-- 动态关联用户资料表 -->
  5.     <if test="includeProfile">
  6.         LEFT JOIN user_profile up ON u.id = up.user_id
  7.     </if>
  8.     <!-- 动态关联角色表 -->
  9.     <if test="includeRoles">
  10.         LEFT JOIN user_role ur ON u.id = ur.user_id
  11.         LEFT JOIN role r ON ur.role_id = r.id
  12.     </if>
  13.     WHERE u.id = #{userId}
  14. </select>
复制代码
  根据条件决定是否关联其他表。
     动态地从多个表中获取用户详细信息。
    代码剖析
  

  • <select id="getUserDetails" resultMap="UserDetailMap">: 定义了这个查询的唯一标识符,可以在Java代码中通过这个ID来调用该查询,并指定告终果映射(resultMap)。
  • SELECT u.* FROM user u: 选择了user表中的全部列,并给这个表起了一个别名u。
  • 动态关联用户资料表:
    1. <if test="includeProfile">
    2.     LEFT JOIN user_profile up ON u.id = up.user_id
    3. </if>
    复制代码

    • 检查传入的参数includeProfile是否为true。假如为true,则执行内部的SQL片断。

  • 动态关联角色表:
    1. <if test="includeRoles">
    2.     LEFT JOIN user_role ur ON u.id = ur.user_id
    3.     LEFT JOIN role r ON ur.role_id = r.id
    4. </if>
    复制代码

    • 检查传入的参数includeRoles是否为true。假如为true,则执行内部的SQL片断。

  • WHERE u.id = #{userId}: 这条语句用于过滤结果,只返回指定用户ID的数据。
  
  调用
传参:
  

  • includeProfile = true
  • includeRoles = true
  • userId = 1
  天生的SQL:
  1. SELECT u.*
  2. FROM user u
  3. LEFT JOIN user_profile up ON u.id = up.user_id
  4. LEFT JOIN user_role ur ON u.id = ur.user_id
  5. LEFT JOIN role r ON ur.role_id = r.id
  6. WHERE u.id  
复制代码
2. 批量操作优化

  1. <!-- MySQL批量更新 -->
  2. <update id="batchUpdate">
  3.     UPDATE user
  4.     <trim prefix="SET" suffixOverrides=",">
  5.         <trim prefix="username = CASE" suffix="END,">
  6.             <foreach collection="list" item="item">
  7.                 WHEN id = #{item.id} THEN #{item.username}
  8.             </foreach>
  9.         </trim>
  10.     </trim>
  11.     WHERE id IN
  12.     <foreach collection="list" item="item" open="(" separator="," close=")">
  13.         #{item.id}
  14.     </foreach>
  15. </update>
复制代码
  适用于大量数据的批量操作。
     批量更新用户表中的数据。
    代码剖析
  

  • <update id="batchUpdate">: 定义了这个更新操作的唯一标识符,可以在Java代码中通过这个ID来调用该更新操作。
  • UPDATE user: 指定了要更新的表名,这里是user表。
  • 第一个 <trim> 标签:
    1. <trim prefix="SET" suffixOverrides=",">
    2.     ...
    3. </trim>
    复制代码

    • prefix="SET": 在天生的SQL语句前添加SET关键字。
    • suffixOverrides=",": 主动移除天生的SQL语句末尾多余的逗号。

  • 第二个 <trim> 标签:
    1. <trim prefix="username = CASE" suffix="END,">
    2.     ...
    3. </trim>
    复制代码

    • prefix="username = CASE": 在天生的SQL语句前添加username = CASE。
    • suffix="END,": 在天生的SQL语句后添加END,。

  • 嵌套的 <foreach> 标签:
    1. <foreach collection="list" item="item">
    2.     WHEN id = #{item.id} THEN #{item.username}
    3. </foreach>
    复制代码

    • collection="list": 指定要遍历的集合,这里假设传入的参数是一个包罗多个用户的列表。
    • item="item": 定义当前遍历项的变量名,这里是item。

  • WHERE id IN ...:
    1. WHERE id IN
    2. <foreach collection="list" item="item" open="(" separator="," close=")">
    3.     #{item.id}
    4. </foreach>
    复制代码

    • 这部分使用另一个<foreach>标签来天生WHERE id IN (...)子句。

  
  整体效果
  假设你传入的参数是一个包罗两个用户的列表,每个用户都有一个id和一个新的username值:
  1. List<User> userList = new ArrayList<>();
  2. userList.add(new User(1, "newUsername1"));
  3. userList.add(new User(2, "newUsername2"));
复制代码
天生的终极SQL语句将会是:
  1. UPDATE user
  2. SET username = CASE
  3.     WHEN id = 1 THEN 'newUsername1'
  4.     WHEN id = 2 THEN 'newUsername2'
  5. END
  6. WHERE id IN (1, 2);
复制代码

六. 最佳实践

1. 性能优化



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



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



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

七. 留意事项


  • #{} 和 ${} 的区别:

    • #{} 会举行预编译,防止 SQL 注入。
    • ${} 直接更换,有 SQL 注入风险。

  • 动态 SQL 的顺序很紧张,要留意逻辑的先后顺序。
  • 批量操作时留意数据库的性能限制。
  • 复杂查询建议使用 resultMap 而不是 resultType。
  • 对于大量重复的 SQL 片断,建议使用 sql 标签复用。


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

瑞星

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表