MyBatis SQL 映射文件的作用和结构

MyBatis SQL 映射文件定义了 SQL 语句以及如何将 SQL 语句的参数和结果映射到 Java 对象。
一、 作用 (Purpose)

MyBatis SQL 映射文件(通常命名为 XXXMapper.xml)的主要作用是:

  1. 定义 SQL 语句: 在 XML 映射文件中编写 SQL 语句,包括 SELECT, INSERT, UPDATE, DELETE 等各种类型的 SQL 语句。
  2. 参数映射 (Parameter Mapping): 定义如何将 Java 方法的参数映射到 SQL 语句中的参数。 可以使用 #$ 占位符,并指定参数类型、jdbcType 等信息。
  3. 结果映射 (Result Mapping): 定义如何将 SQL 语句的查询结果映射到 Java 对象。 可以使用 resultTyperesultMap,并定义一对一、一对多等关系映射。
  4. 动态 SQL (Dynamic SQL): 使用 MyBatis 提供的动态 SQL 元素 (例如 <if>, <choose>, <when>, <otherwise>, <where>, <set>, <foreach>),根据不同的条件动态生成 SQL 语句。
  5. 缓存配置 (Cache Configuration): 配置 SQL 语句的缓存行为,提高查询性能。
  6. 与 Mapper 接口关联: 将 SQL 映射文件与 Java Mapper 接口关联起来,使得可以通过调用 Mapper 接口的方法来执行 SQL 语句。

总而言之,SQL 映射文件是 MyBatis 将 SQL 语句与 Java 代码解耦的关键,它允许开发者专注于 SQL 语句的编写和优化,而无需关心 JDBC 的细节。

二、 结构 (Structure)

MyBatis SQL 映射文件的根元素是 <mapper>,它包含多个子元素,用于定义 SQL 语句、参数映射、结果映射等信息。 以下是一个典型的 SQL 映射文件结构:

<?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.example.mapper.UserMapper">

    <!-- 1. cache (缓存) -->
    <cache
            eviction="LRU"
            flushInterval="60000"
            readOnly="true"
            size="512"/>

    <!-- 2. resultMap (结果映射) -->
    <resultMap id="UserResultMap" type="com.example.model.User">
        <id property="id" column="id"/>
        <result property="username" column="username"/>
        <result property="email" column="email"/>
        <!-- association (一对一) -->
        <association property="address" column="address_id" javaType="com.example.model.Address"
                     select="com.example.mapper.AddressMapper.selectAddressById"/>
        <!-- collection (一对多) -->
        <collection property="orders" column="id" ofType="com.example.model.Order"
                    select="com.example.mapper.OrderMapper.selectOrdersByUserId"/>
    </resultMap>

    <!-- 3. select (查询) -->
    <select id="selectUserById" parameterType="int" resultMap="UserResultMap" useCache="true">
        SELECT * FROM user WHERE id = #{id}
    </select>

    <!-- 4. insert (插入) -->
    <insert id="insertUser" parameterType="com.example.model.User" useGeneratedKeys="true" keyProperty="id">
        INSERT INTO user (username, email) VALUES (#{username}, #{email})
    </insert>

    <!-- 5. update (更新) -->
    <update id="updateUser" parameterType="com.example.model.User">
        UPDATE user SET username = #{username}, email = #{email} WHERE id = #{id}
    </update>

    <!-- 6. delete (删除) -->
    <delete id="deleteUserById" parameterType="int">
        DELETE FROM user WHERE id = #{id}
    </delete>

    <!-- 7. sql (SQL 片段) -->
    <sql id="userColumns">
        id, username, email
    </sql>

</mapper>

三、各个元素详解

  1. <mapper> (根元素):

    • namespace 属性:指定 Mapper 接口的完全限定名。 MyBatis 会根据这个命名空间来查找 SQL 映射文件,并将 SQL 语句与 Mapper 接口的方法关联起来。 这是将 SQL 映射文件与 Java 代码关联的关键。
      例如:<mapper namespace="com.example.mapper.UserMapper"> 对应着 UserMapper.java 接口文件
  2. <cache> (缓存):

    • 配置该 Mapper 对应的二级缓存。
    • eviction 属性:指定缓存的淘汰策略 (LRU, FIFO, SOFT, WEAK)。
    • flushInterval 属性:指定缓存的刷新间隔 (毫秒)。
    • size 属性:指定缓存的最大容量。
    • readOnly 属性:指定缓存是否只读 (truefalse)。
    • <cache type="org.mybatis.cache.impl.PerpetualCache"/> 使用自定义缓存
  3. <cache-ref> (缓存引用):

    • 引用其他 Mapper 的缓存配置。
    • namespace 属性:指定要引用的 Mapper 的命名空间。
  4. <resultMap> (结果映射):

    • 作用: 定义如何将 SQL 语句的查询结果映射到 Java 对象。

    • id 属性:指定 resultMap 的唯一标识。

    • type 属性:指定要映射的 Java 类型。

    • 子元素:

      • <id>:定义主键映射。
        • property 属性:指定 Java 对象的属性名。
        • column 属性:指定数据库表中的列名。
      • <result>:定义普通属性映射。
        • property 属性:指定 Java 对象的属性名。
        • column 属性:指定数据库表中的列名。
      • <association>:定义一对一关系映射。
        • property 属性:指定 Java 对象的属性名。
        • column 属性:指定数据库表中的列名。
        • javaType 属性:指定关联对象的 Java 类型。
        • select 属性:指定用于查询关联对象的 SQL 语句的 ID。
      • <collection>:定义一对多关系映射。
        • property 属性:指定 Java 对象的属性名。
        • column 属性:指定数据库表中的列名。
        • ofType 属性:指定集合中元素的 Java 类型。
        • select 属性:指定用于查询集合元素的 SQL 语句的 ID。
      • <discriminator>:定义鉴别器,根据不同的条件选择不同的映射规则。
        • column 属性:指定用于鉴别的列名。
        • <case> 元素:定义不同的映射规则。
          • value 属性:指定鉴别值。
          • resultMap 属性:指定要使用的 resultMap
    • 示例:

      <resultMap id="UserResultMap" type="com.example.model.User">
          <id property="id" column="id"/>
          <result property="username" column="username"/>
          <result property="email" column="email"/>
          <association property="address" column="address_id" javaType="com.example.model.Address"
                       select="com.example.mapper.AddressMapper.selectAddressById"/>
          <collection property="orders" column="id" ofType="com.example.model.Order"
                      select="com.example.mapper.OrderMapper.selectOrdersByUserId"/>
      </resultMap>
      
  5. <select> (查询):

    • 作用: 定义 SELECT 语句,用于查询数据。

    • id 属性:指定 SQL 语句的唯一标识。 与 Mapper 接口中的方法名对应。

    • parameterType 属性:指定参数类型。

    • resultType 属性:指定结果类型(如果使用简单类型映射)。

    • resultMap 属性:指定结果映射 (如果使用 <resultMap> 元素)。

    • parameterMap 属性: (已经过时, 不建议使用)

    • flushCache 属性: 如果设置为 true,则每次执行该语句都会刷新缓存。

    • useCache 属性:如果设置为 true,则该语句的结果会被缓存。

    • timeout 属性:设置超时时间(秒)。

    • fetchSize 属性:设置每次从数据库获取的记录数量。

    • statementType 属性: 指Statement类型, 可选值为 STATEMENT、PREPARED 和 CALLABLE。

      • STATEMENT, 默认值, 使用Statement
      • PREPARED, 使用PreparedStatement, 可以防止SQL注入, 性能更好。
      • CALLABLE, 主要用于执行存储过程
    • 示例:

      <select id="selectUserById" parameterType="int" resultMap="UserResultMap" useCache="true">
          SELECT * FROM user WHERE id = #{id}
      </select>
      
  6. <insert> (插入):

    • 作用: 定义 INSERT 语句,用于插入数据。

    • id 属性:指定 SQL 语句的唯一标识。

    • parameterType 属性:指定参数类型。

    • useGeneratedKeys 属性:是否允许 MyBatis 使用 JDBC 的 getGeneratedKeys 方法获取自增主键值。

    • keyProperty 属性:指定 Java 对象的哪个属性用于接收自增主键值。

    • keyColumn属性:指定数据库表的主键列名.

    • 示例:

      <insert id="insertUser" parameterType="com.example.model.User" useGeneratedKeys="true" keyProperty="id" keyColumn="id">
          INSERT INTO user (username, email) VALUES (#{username}, #{email})
      </insert>
      
  7. <update> (更新):

    • 作用: 定义 UPDATE 语句,用于更新数据。

    • id 属性:指定 SQL 语句的唯一标识。

    • parameterType 属性:指定参数类型。

    • 示例:

      <update id="updateUser" parameterType="com.example.model.User">
          UPDATE user SET username = #{username}, email = #{email} WHERE id = #{id}
      </update>
      
  8. <delete> (删除):

    • 作用: 定义 DELETE 语句,用于删除数据。

    • id 属性:指定 SQL 语句的唯一标识。

    • parameterType 属性:指定参数类型。

    • 示例:

      <delete id="deleteUserById" parameterType="int">
          DELETE FROM user WHERE id = #{id}
      </delete>
      
  9. <sql> (SQL 片段):

    • 作用: 定义可以重复使用的 SQL 代码片段。

    • id 属性:指定 SQL 片段的唯一标识。

    • 示例:

      <sql id="userColumns">
          id, username, email
      </sql>
      

四、 动态 SQL 元素 (Dynamic SQL Elements)

MyBatis 提供了以下动态 SQL 元素,可以根据不同的条件动态生成 SQL 语句:

  1. <if>

    • 作用: 根据条件判断是否包含某段 SQL 代码。

    • test 属性:指定判断条件,使用 OGNL 表达式。

    • 示例:

      <select id="selectUserByCondition" parameterType="com.example.model.User" resultMap="UserResultMap">
          SELECT * FROM user
          <where>
              <if test="username != null and username != ''">
                  AND username = #{username}
              </if>
              <if test="email != null and email != ''">
                  AND email = #{email}
              </if>
          </where>
      </select>
      
  2. <choose>, <when>, <otherwise>

    • 作用: 类似于 Java 中的 switch-case 语句,用于选择其中一个条件分支。

    • <choose> 元素:包含多个 <when> 元素和一个 <otherwise> 元素。

    • <when> 元素:指定条件和对应的 SQL 代码。

    • <otherwise> 元素:指定默认的 SQL 代码(当所有 <when> 条件都不满足时执行)。

    • test 属性:指定 <when> 元素的判断条件,使用 OGNL 表达式。

    • 示例:

      <select id="selectUserByCondition" parameterType="com.example.model.User" resultMap="UserResultMap">
          SELECT * FROM user
          <where>
              <choose>
                  <when test="username != null and username != ''">
                      AND username = #{username}
                  </when>
                  <when test="email != null and email != ''">
                      AND email = #{email}
                  </when>
                  <otherwise>
                      AND 1 = 1
                  </otherwise>
              </choose>
          </where>
      </select>
      
  3. <where>

    • 作用: 动态生成 WHERE 子句,并自动处理 ANDOR 关键字。

    • 如果 <where> 元素内部有任何内容,它会自动添加 WHERE 关键字。

    • 如果 <where> 元素内部的内容以 ANDOR 开头,它会自动移除这些关键字。

    • 示例:

      <select id="selectUserByCondition" parameterType="com.example.model.User" resultMap="UserResultMap">
          SELECT * FROM user
          <where>
              <if test="username != null and username != ''">
                  AND username = #{username}
              </if>
              <if test="email != null and email != ''">
                  AND email = #{email}
              </if>
          </where>
      </select>
      
  4. <set>

    • 作用: 动态生成 SET 子句,用于 UPDATE 语句,并自动处理逗号 ,

    • 如果 <set> 元素内部有任何内容,它会自动添加 SET 关键字。

    • 如果 <set> 元素内部的内容以逗号 , 开头,它会自动移除这个逗号。

    • 示例:

      <update id="updateUserSelective" parameterType="com.example.model.User">
          UPDATE user
          <set>
              <if test="username != null">
                  username = #{username},
              </if>
              <if test="email != null">
                  email = #{email},
              </if>
          </set>
          WHERE id = #{id}
      </update>
      
  5. <trim>

    • 作用: 更通用的动态 SQL 元素,可以自定义前缀、后缀、以及前缀和后缀要移除的内容。

    • prefix 属性:指定前缀。

    • suffix 属性:指定后缀。

    • prefixOverrides 属性:指定要移除的前缀。

    • suffixOverrides 属性:指定要移除的后缀。

    • 示例:

      <select id="selectUserByCondition" parameterType="com.example.model.User" resultMap="UserResultMap">
          SELECT * FROM user
          <trim prefix="WHERE" prefixOverrides="AND |OR">
              <if test="username != null and username != ''">
                  AND username = #{username}
              </if>
              <if test="email != null and email != ''">
                  AND email = #{email}
              </if>
          </trim>
      </select>
      
      <update id="updateUserSelective" parameterType="com.example.model.User">
          UPDATE user
          <trim prefix="SET" suffixOverrides=",">
              <if test="username != null">
                  username = #{username},
              </if>
              <if test="email != null">
                  email = #{email},
              </if>
          </trim>
          WHERE id = #{id}
      </update>
      
  6. <foreach>

    • 作用: 用于遍历集合,生成重复的 SQL 代码。

    • collection 属性:指定要遍历的集合。

    • item 属性:指定集合中元素的别名。

    • index 属性:指定当前元素的索引的别名。

    • open 属性:指定循环开始时的字符串。

    • close 属性:指定循环结束时的字符串。

    • separator 属性:指定元素之间的分隔符。

    • 示例:

      <select id="selectUsersByIds" parameterType="list" resultMap="UserResultMap">
          SELECT * FROM user
          WHERE id IN
          <foreach item="id" collection="list" open="(" separator="," close=")">
              #{id}
          </foreach>
      </select>
      
      <insert id="insertUsers" parameterType="list">
          INSERT INTO user (username, email) VALUES
          <foreach item="user" collection="list" separator="," >
              (#{user.username}, #{user.email})
          </foreach>
      </insert>
      
  7. <bind>

    • 作用: 创建一个变量,并将其绑定到 OGNL 表达式的结果。
    • name 属性: 指定变量名
    • value 属性: 指定 OGNL 表达式
    • 示例:
      <select id="selectUsersBySearchTerm" parameterType="string" resultMap="UserResultMap">
          <bind name="pattern" value="'%' + searchTerm + '%'" />
          SELECT * FROM user
          WHERE username LIKE #{pattern} OR email LIKE #{pattern}
      </select>
      

五、 DOCTYPE (Document Type Definition)

MyBatis SQL 映射文件需要遵循特定的 DTD 约束.

  • DTD 声明:

    <!DOCTYPE mapper
            PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    
  • DTD 文件:

    • mybatis-3-mapper.dtd 文件定义了 MyBatis SQL 映射文件的结构。可以在 MyBatis 的官方网站上找到该文件。
    • 开发中通常不需要我们手动修改 DTD 文件,只需要在 XML 配置文件中声明 DTD 即可。

六、总结

MyBatis SQL 映射文件是 MyBatis 框架的核心,它定义了 SQL 语句以及如何将 SQL 语句的参数和结果映射到 Java 对象。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冰糖心书房

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值