Mybatis-xml配置文件

Mybatis-xml配置文件

Mapper配置文件

  • Mapper 配置文件用于定义 SQL 语句和映射规则。每个 Mapper 文件通常对应一个数据库的操作
  • 每个数据库表对应一个类
  • 每个mapper接口也对应该数据库中的这个表
  • (mapper接口------mapper配置文件-------pojo类)共同对应所连接数据库中的一张表

Mapper 配置文件是一个 XML 文件,通常与 Mapper 接口一一对应。其基本结构如下:

<?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">
  <!-- SQL 语句定义 -->
</mapper>
  • <mapper>:根元素,namespace 属性指定对应的 Mapper 接口的全限定名。
  • SQL 语句定义:在 <mapper> 标签内定义具体的 SQL 语句。

SQL语句定义

  • Mapper 配置文件支持定义以下类型的 SQL 语句:
    • <select>:查询语句。
    • <insert>:插入语句。
    • <update>:更新语句。
    • <delete>:删除语句。

<select> 查询语句

  • 用于执行查询操作,并将结果映射到 Java 对象中

    //接口方法
    User selectUser(int id);
    
    <!-- 对应xml配置 -->
    <select id="selectUser" resultType="com.example.model.User">
      SELECT * FROM user WHERE id = #{id}
    </select>
    
    • id:对应 Mapper 接口中的方法名。
    • resultType:指定返回结果的 Java 类型。
    • #{id}:参数占位符,id 是Mapper接口方法参数名

<insert> 插入语句

  • 用于执行插入操作

    <insert id="insertUser" parameterType="com.example.model.User">
      INSERT INTO user (name, age) VALUES (#{name}, #{age})
    </insert>
    
    • parameterType:指定参数类型。
    • #{name}#{age}:参数占位符,对应 Java 对象的属性

<update> 更新语句

  • 用于执行更新操作

    <update id="updateUser" parameterType="com.example.model.User">
      UPDATE user SET name = #{name}, age = #{age} WHERE id = #{id}
    </update>
    

<delete> 删除语句

  • 用于执行删除操作

    <delete id="deleteUser" parameterType="int">
      DELETE FROM user WHERE id = #{id}
    </delete>
    

xml文件中获取参数

  1. 单个参数

    如果 Mapper 接口方法只有一个参数,可以直接在 XML 文件中通过 #{参数名} 获取参数值

    User selectUser(int id);
    
    <select id="selectUser" resultType="com.example.model.User">
      SELECT * FROM user WHERE id = #{id}
    </select>
    
  2. 多个参数

    如果 Mapper 接口方法有多个参数,可以通过以下两种方式传递参数

    • 使用 @Param 注解为每个参数指定名称,然后在 XML 文件中通过 #{参数名} 获取参数值

    • 不能使用#{}直接获取参数值,报错,必须加上 @Param 注解

      User selectUserByNameAndAge(@Param("name") String name, @Param("age") int age);
      
      <select id="selectUserByNameAndAge" resultType="com.example.model.User">
        SELECT * FROM user WHERE name = #{name} AND age = #{age}
      </select>
      
      • #{name}#{age}:通过 @Param 注解指定的参数名获取参数值
    • 将多个参数封装到一个 Map 中,然后在 XML 文件中通过 #{key} 获取参数值

      User selectUserByMap(Map<String, Object> params);
      
      <select id="selectUserByMap" resultType="com.example.model.User">
        SELECT * FROM user WHERE name = #{name} AND age = #{age}
      </select>
      
      • #{name}#{age}:通过 Map 的键获取参数值
  3. 对象参数

    如果 Mapper 接口方法的参数是一个 Java 对象,可以直接在 XML 文件中通过 #{属性名} 获取对象的属性值

    void insertUser(User user);
    
    <insert id="insertUser" parameterType="com.example.model.User">
      INSERT INTO user (name, age) VALUES (#{name}, #{age})
    </insert>
    
    • #{name}#{age}通过 Java 对象的属性名获取属性值
  4. 参数类型为集合或者数组

    如果 Mapper 接口方法的参数是集合(如 List)或数组,可以通过 <foreach> 标签遍历集合或数组

    如果参数是 ListparameterType 可以写为 java.util.List 或者直接省略

    List<User> selectUsersByIds(@Param("ids") List<Integer> ids);
    
    <select id="selectUsersByIds" resultType="com.example.model.User">
      SELECT * FROM user
      WHERE id IN
      <foreach collection="ids" item="id" open="(" separator="," close=")">
        #{id}
      </foreach>
    </select>
    
    • collection="ids":指定集合参数的名称。
    • item="id":指定集合中每个元素的变量名。
    • #{id}:通过 item 指定的变量名获取集合中的元素值
  5. 参数类型为map

    如果 Mapper 接口方法的参数是 Map,可以直接在 XML 文件中通过 #{key} 获取 Map 中的值

  6. 参数类型为多个 Java 对象

    如果 Mapper 接口方法的参数是多个 Java 对象,可以通过 @Param 注解为每个对象指定名称,然后在 XML 文件中通过 #{对象名.属性名} 获取属性值

    void updateUser(@Param("user") User user, @Param("condition") UserCondition condition);
    
    <update id="updateUser">
      UPDATE user
      SET name = #{user.name}, age = #{user.age}
      WHERE id = #{condition.id}
    </update>
    

接口和xml文件中返回值的匹配

MyBatis 通过以下方式将 SQL 查询结果映射到 Mapper 接口方法的返回值

  • resultType:指定返回值的 Java 类型(适用于简单映射)。
  • resultMap:指定返回值的映射规则(适用于复杂映射)
  1. 返回值类型为基本类型或包装类型

    • 如果 Mapper 接口方法的返回值是基本类型(如 intString)或包装类型(如 IntegerLong),可以直接在 XML 文件中使用 resultType 指定返回值类型

      int countUsers();
      
      <select id="countUsers" resultType="int">
        SELECT COUNT(*) FROM user
      </select>
      
      • resultType="int":指定返回值为 int 类型
      • int类型要求返回值不能为null
      • Integer可以为null
  2. 返回值类型为 Java 对象

    • 如果 Mapper 接口方法的返回值是一个 Java 对象,可以在 XML 文件中使用 resultTyperesultMap 指定返回值类型

    • 使用 resultType

      User selectUser(int id);
      
      <select id="selectUser" resultType="com.example.model.User">
        SELECT * FROM user WHERE id = #{id}
      </select>
      
      • resultType="com.example.model.User":指定返回值为 User 类型
    • 使用 resultMap,如果返回值需要复杂的映射规则,可以使用 resultMap

      User selectUserDetail(int id);
      
      <resultMap id="userResultMap" type="com.example.model.User">
        <id property="id" column="id"/> 
        <result property="name" column="name"/>
        <result property="age" column="age"/>
        <!--property代表User中的属性值,column代表数据库列的名称-->
      </resultMap>
      
      <select id="selectUserDetail" resultMap="userResultMap">
        SELECT * FROM user WHERE id = #{id}
      </select>
      
  3. 返回值类型为集合

    • 如果 Mapper 接口方法的返回值是一个集合(如 List),可以在 XML 文件中使用 resultTyperesultMap 指定集合中元素的类型

      List<User> selectAllUsers();
      
      <select id="selectAllUsers" resultType="com.example.model.User">
        SELECT * FROM user
      </select>
      
  4. 返回值类型为 Map

    • 如果 Mapper 接口方法的返回值是一个 Map,可以在 XML 文件中使用 resultTyperesultMap 指定返回值类型

      Map<String, Object> selectUserAsMap(int id);
      
      <select id="selectUserAsMap" resultType="map">
        SELECT * FROM user WHERE id = #{id}
      </select>
      
  5. 返回值类型为嵌套对象

    • 如果 Mapper 接口方法的返回值是一个嵌套对象(如包含嵌套对象的 Java 对象),可以使用 resultMap 定义复杂的映射规则

      UserDetail selectUserDetail(int id);
      
      <resultMap id="userDetailResultMap" type="com.example.model.UserDetail">
        <id property="id" column="id"/>
        <result property="name" column="name"/>
        <result property="age" column="age"/>
        <association property="address" javaType="com.example.model.Address">
          <result property="city" column="city"/>
          <result property="street" column="street"/>
        </association>
        <collection property="orders" ofType="com.example.model.Order">
          <result property="orderId" column="order_id"/>
          <result property="amount" column="amount"/>
        </collection>
      </resultMap>
      
      <select id="selectUserDetail" resultMap="userDetailResultMap">
        SELECT u.*, a.city, a.street, o.order_id, o.amount
        FROM user u
        LEFT JOIN address a ON u.id = a.user_id
        LEFT JOIN orders o ON u.id = o.user_id
        WHERE u.id = #{id}
      </select>
      
      • resultMap="userDetailResultMap":指定返回值的映射规则。
      • <association>:用于映射嵌套对象。
      • <collection>:用于映射嵌套集合
  6. 分不同表的嵌套对象

    • <association> 标签(对应 @One

    • 假设有两个表:user 表和 address 表,一个用户对应一个地址

    • 实体类

    • public class User {
          private int id;
          private String username;
          private Address address; // 一对一关系
          // Getters and Setters
      }
      
      public class Address {
          private int id;
          private String city;
          private String street;
          // Getters and Setters
      }
      
    • XML 配置

      <resultMap id="userResultMap" type="User">
          <id property="id" column="id"/>
          <result property="username" column="username"/>
          <!-- 一对一关系 -->
          <association property="address" column="address_id" javaType="Address" select="selectAddressById"/>
      </resultMap>
      
      <select id="selectUserById" resultMap="userResultMap">
          SELECT id, username, address_id FROM user WHERE id = #{id}
      </select>
      
      <select id="selectAddressById" resultType="Address">
          SELECT id, city, street FROM address WHERE id = #{address_id}
      </select>
      
    • <association> 标签用于定义一对一关系。

      • property="address": 指定 User 对象中的 address 属性。
      • column="address_id": 指定查询结果中的 address_id 列作为参数传递给嵌套查询。
      • select="selectAddressById": 指定使用 selectAddressById 方法查询 Address 对象。
    • selectAddressById: 根据 address_id 查询 Address 对象

  7. <collection> 标签(对应 @Many

    • <collection> 标签用于处理 一对多 的关系,即一个对象中包含一个集合

    • 假设有两个表:user 表和 order 表,一个用户对应多个订单

    • 实体类

    • public class User {
          private int id;
          private String username;
          private List<Order> orders; // 一对多关系
          // Getters and Setters
      }
      
      public class Order {
          private int id;
          private String orderNo;
          // Getters and Setters
      }
      
    • xml配置

    • <resultMap id="userResultMap" type="User">
          <id property="id" column="id"/>
          <result property="username" column="username"/>
          <!-- 一对多关系 -->
          <collection property="orders" column="id" ofType="Order" select="selectOrdersByUserId"/>
      </resultMap>
      
      <select id="selectUserById" resultMap="userResultMap">
          SELECT id, username FROM user WHERE id = #{id}
      </select>
      
      <select id="selectOrdersByUserId" resultType="Order">
          SELECT id, order_no FROM orders WHERE user_id = #{userId}
      </select>
      
    • <collection> 标签用于定义一对多关系。

      • property="orders": 指定 User 对象中的 orders 属性。
      • column="id": 指定查询结果中的 id 列作为参数传递给嵌套查询。
      • ofType="Order": 指定集合中的元素类型为 Order
      • select="selectOrdersByUserId": 指定使用 selectOrdersByUserId 方法查询 Order 列表。
    • selectOrdersByUserId: 根据 user_id 查询 Order 列表

xml中parameterType 和 resultType的声明

parameterType

  • 无需显示定义
    • 单参数且类型可由 MyBatis 推断
      • 如果传入的参数类型为基本类型或者包装类(如 String 或 Integer),MyBatis 可以自动推断出其类型,此时无需显式定义 parameterType
      • 单个对象类型也行,建议加上
    • 使用 @Param 注解
      • 当传入多个参数并在接口方法中使用 @Param 注解标注参数名时,无需显式定义 parameterType,MyBatis 会通过参数名自动匹配
  • 需要显示定义
    • 如果参数是 Map,显式定义 parameterTypejava.util.Map 可以提高可读性
    • 如果参数是自定义对象,显式定义 parameterType 为对象的全限定类名可以避免歧义
    • 如果参数是集合类型(如 ListSet、数组),显式定义 parameterType 可以提高代码的可读性
      • parameterType="java.util.List"
      • parameterType="java.util.Set"
      • parameterType="java.lang.Integer[]"

resultType

  • 如果返回值是基本类型(如 intlong)或包装类型(如 IntegerLong),必须显式定义 resultType
  • 所有返回数据的 SQL 查询(SELECT 语句)除了返回值为void以外,必须都必须显式定义 resultType
  • 更新类操作(DML)的返回值通常是受影响的行数(int 或 Integer),不需要显式指定 resultType,MyBatis 会自动处理

select标签中常用属性

属性名 描述
id 唯一标识符,对应 Mapper 接口中的方法名。
resultType 指定查询结果的 Java 类型(通常是实体类)。
resultMap 指定结果映射的 ID(用于复杂映射)。
parameterType 指定参数类型(可选)。
flushCache 是否清空缓存(默认 false)。
useCache 是否使用二级缓存(默认 true)。
timeout 设置查询超时时间(单位:秒)。
fetchSize 设置每次从数据库获取的记录数。
statementType 指定 SQL 语句类型(STATEMENTPREPAREDCALLABLE,默认 PREPARED)。
resultSetType 指定结果集类型(FORWARD_ONLYSCROLL_INSENSITIVESCROLL_SENSITIVE)。

动态SQL的拼接

在 MyBatis 中,动态 SQL 是一种强大的功能,允许根据条件动态拼接 SQL 语句。通过动态 SQL,可以避免在 Java 代码中手动拼接 SQL 字符串,从而提高代码的可读性和可维护性。MyBatis 提供了多种标签来实现动态 SQL

  1. 标签

    • 作用:根据条件判断是否包含某段 SQL。
    • 使用场景:当某个条件存在时,才拼接对应的 SQL 片段
    <select id="selectUsersByCondition" resultType="User">
        SELECT * FROM user
        WHERE 1=1
        <if test="name != null">
            AND name = #{name}
        </if>
        <if test="age != null">
            AND age = #{age}
        </if>
    </select>
    
    • test 属性:用于指定条件表达式,支持 OGNL 表达式。
    • 如果 name 不为空,则拼接 AND name = #{name}
    • 如果 age 不为空,则拼接 AND age = #{age}
    • <if test="name != null"> 中的 name 会通过反射或 Map 的 get() 方法获取值。若参数对象中存在该字段且非空,则动态拼接对应的 SQL 条件
    • 如果参数是一个 Maptest 属性中使用 Map 的键名。
    • 如果参数是多个简单类型(如 Stringint),需要使用 @Param 注解指定参数名
  2. 标签

    • 作用:自动处理 WHERE 子句的开头和多余的 ANDOR
    • 使用场景:避免手动处理 WHERE 子句的拼接
    <select id="selectUsersByCondition" resultType="User">
        SELECT * FROM user
        <where>
            <if test="name != null">
                AND name = #{name}
            </if>
            <if test="age != null">
                AND age = #{age}
            </if>
        </where>
    </select>
    
    • 如果 nameage 都为空,<where> 标签不会生成 WHERE 子句。
    • 如果 name 不为空,<where> 标签会自动去掉开头的 AND
  3. 标签

    • 作用:实现类似 if-elseswitch-case 的逻辑。
    • 使用场景:根据条件选择不同的 SQL 片段
    <select id="selectUsersByCondition" resultType="User">
        SELECT * FROM user
        <where>
            <choose>
                <when test="name != null">
                    AND name = #{name}
                </when>
                <when test="age != null">
                    AND age = #{age}
                </when>
                <otherwise>
                    AND status = 1
                </otherwise>
            </choose>
        </where>
    </select>
    
    • 如果 name 不为空,拼接 AND name = #{name}
    • 如果 name 为空但 age 不为空,拼接 AND age = #{age}
    • 如果 nameage 都为空,拼接 AND status = 1
  4. 标签

    • 作用:遍历集合或数组,生成动态 SQL。
    • 使用场景:用于 IN 查询或批量操作
    <select id="selectUsersByIdList" resultType="User">
        SELECT * FROM user
        WHERE id IN
        <foreach collection="idList" item="id" open="(" separator="," close=")">
            #{id}
        </foreach>
    </select>
    
    • collection:集合或数组的名称。
    • item:集合中每个元素的别名。
    • open:生成的 SQL 片段的前缀。
    • separator:元素之间的分隔符。
    • close:生成的 SQL 片段的后缀。
  5. 标签

    • 作用:自动处理 UPDATE 语句中的 SET 子句,去掉多余的逗号。
    • 使用场景:动态更新字段
    <update id="updateUser" parameterType="User">
        UPDATE user
        <set>
            <if test="name != null">
                name = #{name},
            </if>
            <if test="age != null">
                age = #{age},
            </if>
        </set>
        WHERE id = #{id}
    </update>
    
    • 如果 name 不为空,拼接 name = #{name},
    • 如果 age 不为空,拼接 age = #{age},
    • <set> 标签会自动去掉最后一个多余的逗号
posted @ 2025-03-17 22:00  QAQ001  阅读(213)  评论(0)    收藏  举报