大厂Java面试题:MyBatis的映射器(Mapper.xml)中有哪些常见的元素?

大家好,我是王有志。今天给大家带来的是一道来自京东的 MyBatis 面试题:MyBatis的映射器(Mapper.xml)中有哪些常见的元素?
MyBatis 的映射器中提供了 9 个顶级元素,按照功能可以分为 3 类:

  • SQL 语句相关的元素:sql 元素,select 元素,insert 元素,update 元素和 delete 元素;
  • 参数映射与结果集映射相关元素:parameterMap 元素和 resultMap 元素;
  • 二级缓存相关元素:cache 元素和 cache-ref 元素。

其中与参数映射有关的 parameterMap 元素,已经被 MyBatis 官方标记为废弃,因此不建议大家在项目中使用(下文也不会展示 parameterMap 元素的用法)。
除了上面 9 个顶级元素外,MyBatis 的映射器中还提供了非常多的二级元素,常用的有以下 6 个元素:

  • include 元素
  • if 元素
  • foreach 元素
  • trim 元素,where 元素和 set 元素

下面我们来逐个解释它们的含义,并展示它们的用法。

sql 元素与 include 元素的使用

sql 元素用于定义可重复使用的 SQL 语句片段
下面我们使用 sql 元素定义一段 SQL 语句片段,代码如下:

<sql id="Base_Column_List">
  item_id, order_id, commodity_id, commodity_price, commodity_count
</sql>

include 元素用于引入由 SQL 元素定义的 SQL 语句片段
下面我们使用 include 元素引入 SQL 语句片段,代码如下:

<select id="selectOrderItemByOrderId" resultType="com.wyz.entity.OrderItemDO">
  select
  <include refid="Base_Column_List"/>
  from order_item where order_id = #{orderId, jdbcType=INTEGER}
</select>

select 元素,if 元素与 where 元素的使用

select 元素用于定义查询语句;if 元素可以在映射器中实现条件判断语句,与 Java 中的关键字 if 的作用相同;where 元素会自动移除条件子句前缀的“and”和“or”,并在条件子句的开始处插入“where”,如果不存在条件子句,则不会插入“where”
下面我们使用 select 元素实现查询语句,并且将 where 元素和 if 元素组合使用,实现动态的条件查询子句,代码如下:

<select id="selectByItemIdAndOrderId" resultType="com.wyz.entity.OrderItemDO">
  select * from order_item
  <where>
    <if test="orderItem.itemId != null">
      and item_id = #{orderItem.itemId, jdbcType=INTEGER}
    </if>
    <if test="orderItem.orderId != null">
      and order_id = #{orderItem.orderId, jdbcType=INTEGER}
    </if>
  </where>
</select>

insert 元素的使用

insert 元素用于定义插入语句
下面我们使用 insert 元素实现插入语句,代码如下:

<insert id="insert" parameterType="com.wyz.entity.OrderItemDO">
  insert into order_item (item_id, order_id, commodity_id, commodity_price, commodity_count)
  value (#{orderItem.itemId, jdbcType=INTEGER},
  #{orderItem.orderId, jdbcType=INTEGER},
  #{orderItem.commodityId, jdbcType=INTEGER},
  #{orderItem.commodityPrice, jdbcType=DECIMAL},
  #{orderItem.commodityCount, jdbcType=INTEGER})
</insert>

update 元素和 set 元素的使用

update 元素用于定义更新语句;set 元素会自动将子句结尾处的“,”移除,并在子句的开始处插入“set”,如果不存在子句,则不会插入“set”
下面我们使用 update 元素实现更新语句,并使用 set 元素实现动态组装被更新的字段,代码如下:

<update id="updateByItemId" parameterType="com.wyz.entity.OrderItemDO">
  update order_item
  <set>
    <if test="orderItem.commodityId != null">
      commodity_id = #{orderItem.commodityId, jdbcType=INTEGER},
    </if>
    <if test="orderItem.commodityPrice != null">
      commodity_price = #{orderItem.commodityPrice, jdbcType=DECIMAL},
    </if>
    <if test="orderItem.commodityCount != null">
      commodity_count = #{orderItem.commodityCount, jdbcType=INTEGER}
    </if>
  </set>
  where item_id = #{orderItem.itemId, jdbcType=INTEGER}
</update>

delete 元素和 trim 元素

delete 元素用于定义删除语句;trim 元素用于处理子句,根据 prefixOverrides 属性和 suffixOverrides 属性的配置移除子句前后缀的字符串,最后根据 prefix 属性和 suffix 属性的配置,在子句的开始处和结尾处插入字符串。在 MyBatis 的源码实现中,处理 trim 元素的 TrimSqlNode 是处理 where 元素的 WhereSqlNode 和处理 set 元素的 SetSqlNode 的父类
下面我们使用 delete 元素实现删除语句,并使用 trim 元素实现动态的条件语句,代码如下:

<delete id="delete">
  delete from order_item
  where
  <trim prefixOverrides="and">
    <if test="orderItem.itemId != null">
      and item_id = #{orderItem.itemId, jdbcType=INTEGER}
    </if>
    <if test="orderItem.orderId != null">
      and order_id = #{orderItem.orderId,jdbcType=INTEGER}
    </if>
    <if test="orderItem.commodityId != null">
      and commodity_id = #{orderItem.commodityId, jdbcType=INTEGER}
    </if>
    <if test="orderItem.commodityPrice != null">
      and commodity_price = #{orderItem.commodityPrice, jdbcType=DECIMAL}
    </if>
    <if test="orderItem.commodityCount != null">
      and commodity_count = #{orderItem.commodityCount, jdbcType=INTEGER}
    </if>
  </trim>
</delete>

Tips:上面的例子并不好,因为这里完全可以使用 where 元素代替 trim 元素,这里只是为了展示 trim 元素的用法。

foreach 元素的使用

foreach 元素提供了在 MyBatis 映射器中遍历集合与字典的能力,foreach 元素定义了 6 个属性:

属性说明
collection传入的集合或字典的名称(即入参名称)
item集合中迭代元素的别名
index当前元素在集合中的下标(从 0 开始)
open指定开始处的字符串
close指定结尾处的字符串
separator指定元素间分割的字符串

下面我们使用 foreach 元素,实现在 MyBatis 映射器中遍历集合,代码如下:

<select id="selectByItemIds" resultMap="BaseResultMap">
  select * from order_item
  where item_id in
  <foreach collection="itemIds" item="itemId" separator="," open="(" close=")">
    #{itemId, jdbcType=INTEGER}
  </foreach>
</select>

resultMap 元素的使用

resultMap 元素用于定义数据库结果集与 Java 对象之间的映射规则,resultMap 元素本身非常复杂,不过在这里我们只展示它最基础的用法。
下面我们使用 resultMap 元素来定义数据库结果集与 Java 对象之间的映射规则,代码如下:

<resultMap id="BaseResultMap" type="com.wyz.entity.OrderItemDO">
  <id property="itemId" column="item_id" jdbcType="INTEGER"/>
  <result property="orderId" column="order_id" jdbcType="INTEGER"/>
  <result property="commodityId" column="commodity_id" jdbcType="INTEGER"/>
  <result property="commodityPrice" column="commodity_price" jdbcType="DECIMAL"/>
  <result property="commodityCount" column="commodity_count" jdbcType="INTEGER"/>
</resultMap>

我们可以在查询语句中直接使用 resultMap 定义的映射规则,稍微修改下“select 元素,if 元素与 where 元素的使用”中的查询语句,代码如下:

<select id="selectByItemIdAndOrderId" resultMap="BaseResultMap">
  select * from order_item
  <where>
    <if test="orderItem.itemId != null">
      and item_id = #{orderItem.itemId, jdbcType=INTEGER}
    </if>
    <if test="orderItem.orderId != null">
      and order_id = #{orderItem.orderId, jdbcType=INTEGER}
    </if>
  </where>
</select>

Tips:注意观察 select 元素中使用的属性是发生了变化的。

cache 元素和 cache-ref 元素的使用

cache 元素用于开启 MyBatis 的二级缓存(需要配置 mybatis-config.xml 中 cacheEnabled 使用),同时它还起到配置 MyBats 二级缓存的作用
下面我们使用 cache 元素开启 MyBatis 的二级缓存,并且使用 LRU 淘汰策略,每隔 60 秒定时刷新缓存,代码如下:

<mapper namespace="com.wyz.mapper.OrderItemMapper">
  <cache eviction="LRU" flushInterval="60000"/>
</mapper>

cache-ref 元素用于引入定义在其它映射器中的二级缓存
下面我们使用 cache-ref 元素来引入上面的二级缓存,代码如下:

<cache-ref namespace="com.wyz.mapper.OrderItemMapper"/>

尾图(二维码).png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

技术范王有志

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

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

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

打赏作者

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

抵扣说明:

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

余额充值