题目
xml 映射文件中,除了常见的 select/insert/update/delete 标签之外,还有哪些标签
答案
@[toc] --- ## 一级标签 The Mapper XML files have only a few first class elements (一级标签): - `cache` – Configuration of the cache for a given namespace. 给定命名空间的缓存配置 - `cache-ref` – Reference to a cache configuration from another namespace. 引用来自另一个命名空间的缓存配置 - `resultMap` – The most complicated and powerful element that describes how to load your objects from the database result sets(描述如何从数据库结果集中加载对象),详细可擦考这篇文章 [MyBatis中强大的resultMap](https://juejin.cn/post/6844903858477481992) > 如果数据库中表的字段与 `User` 类的属性名称一致,我们就可以使用 `resultType` 来返回(注意这是 resultType!而不是 resultMap)。 > > ```xml > <select id="getUsers" resultType="User"> > SELECT > u.id, > u.username, > u.password, > u.address, > u.email > FROM > USER u > </select> > ``` > > 当然,**这是理想状态下,属性和字段名都完全一致的情况**。但事实上,不一致的情况是有的,这时候我们的`resultMap`就要登场了。 > > 如果 `User` 类保持不变,但`SQL`语句发生了变化,将`id`改成了`uid`。 > > ```xml > <select id="getUsers" resultType="User"> > SELECT > u.id as uid, > u.username, > u.password, > u.address, > u.email > FROM > USER u > </select> > ``` > > 那么,在结果集中,我们将会丢失 `id` 数据。这时候我们就可以定义一个`resultMap`,来映射不一样的字段。 > > ```xml > <resultMap id="getUserByIdMap" type="User"> > <result property="id" column="uid"></result> > </resultMap> > ``` > > 然后,我们把上面的 `select` 语句中的 `resultType` 修改为 `resultMap="getUserByIdMap"`。 > > 这里面 `column` 对应的是数据库的列名或别名;`property` 对应的是结果集的字段或属性。 > > 这就是 `resultMap` 最简单,也最基础的用法:字段映射。 - ~~`parameterMap`~~ – **Deprecated!** Old-school way to map parameters. Inline parameters are preferred and this element may be removed in the future. Not documented here. - `SQL` – This element can be used to define a reusable fragment of SQL code that can be included in other statements. 可以被其他语句 included 的可重用的 SQL 块 > 举个例子: > > ```xml > <SQL id="userColumns"> ${alias}.id,${alias}.username,${alias}.password </SQL> > ``` > > The SQL fragment can then be included in another statement, for example: > > ```xml > <select id="selectUsers" resultType="map"> > select > <include refid="userColumns"><property name="alias" value="t1"/></include>, > <include refid="userColumns"><property name="alias" value="t2"/></include> > from some_table t1 > cross join some_table t2 > </select> > ``` - `insert` – A mapped INSERT statement. - `update` – A mapped UPDATE statement. - `delete` – A mapped DELETE statement. - `select` – A mapped SELECT statement. ## 动态标签 - `if`:有条件地包含 where 子句的一部分 > 举个例子: > > ```xml > <select id="findActiveBlogWithTitleLike" resultType="Blog"> > SELECT * FROM BLOG > WHERE state = ‘ACTIVE’ > <if test="title != null"> > AND title like #{title} > </if> > </select> > ``` - `choose`,`when`,`otherwise`:有时我们不希望所有条件都适用,而是希望**在众多选项中仅选择一种情况**。与 Java 中的 switch 语句类似 > 举个例子: > > ```xml > <select id="findActiveBlogLike" > resultType="Blog"> > SELECT * FROM BLOG WHERE state = ‘ACTIVE’ > <choose> > <when test="title != null"> > AND title like #{title} > </when> > <when test="author != null and author.name != null"> > AND author_name like #{author.name} > </when> > <otherwise> > AND featured = 1 > </otherwise> > </choose> > </select> > ``` - `trim`,`where`,`set`:用来截断在 if 语句中冗余的字段 > 举个例子: > > ```xml > <select id="findActiveBlogLike" > resultType="Blog"> > SELECT * FROM BLOG > WHERE > <if test="state != null"> > state = #{state} > </if> > <if test="title != null"> > AND title like #{title} > </if> > <if test="author != null and author.name != null"> > AND author_name like #{author.name} > </if> > </select> > ``` > > **What happens if none of the conditions are met?** You would end up with SQL that looked like this: > > ```xml > SELECT * FROM BLOG > WHERE > ``` > > This would fail. > > MyBatis 有一个简单的解决方案,把 where 改成 `<where>` 标签 > > ```xml > <select id="findActiveBlogLike" > resultType="Blog"> > SELECT * FROM BLOG > <where> > <if test="state != null"> > state = #{state} > </if> > <if test="title != null"> > AND title like #{title} > </if> > <if test="author != null and author.name != null"> > AND author_name like #{author.name} > </if> > </where> > </select> > ``` > > where 标签知道只有在返回内容时才插入 “WHERE”。此外,如果该内容以“AND”或“OR”开头,它知道将其删除。 > > 与 `<where>` 标签类似的是还有 `<set>` > > 当然,如果这俩无法满足你的需求,可以采用 `trim`,比如: > > ```xml > <trim prefix="WHERE" prefixOverrides="AND |OR "> > ... > </trim> > ``` - `foreach`:iterate over a collection,在 SQL 中迭代一个集合 > 举个例子: > > ```xml > <select id="selectPostIn" resultType="domain.blog.Post"> > SELECT * > FROM POST P > <where> > <foreach item="item" index="index" collection="list" > open="ID in (" separator="," close=")" nullable="true"> > #{item} > </foreach> > </where> > </select> > ```