Mapper 文件中全部标签解释与说明

本文主要介绍的是 Mybatis 中对应实体的 mapper.xml 里面的标签说明

Javamybatis 外联标签 mybatis标签详解_User

定义 SQL 语句

select 标签

属性介绍:

  • id :唯一的标识符.映射方法名称
  • parameterType:传给此语句的参数的全路径名或别名 例:com.mybatis.demo.model.User 或 User
  • resultType :语句返回值类型或别名。注意,如果是集合,那么这里填写的是集合的泛型,而不是集合本身(resultType 与 resultMap 不能并用)

示例

<select id="selectById" resultMap="userInfoMap" parameterType="java.lang.Integer">
    select
      <include refid="BASE_COLUMN"/>
    from
    <include refid="BASE_TABLE"/>
    where user_id = #{userId,jdbcType=INTEGER}
</select>

insert 标签

属性介绍:

  • id :唯一的标识符
  • parameterType:传给此语句的参数的全路径名或别名 例:com.mybatis.demo.model.User 或 User

示例

<!--插入变量名  不选择的-->
  <insert id="insert" parameterType="com.tmf.mybatis.demo.model.User">
    insert into
    <include refid="BASE_TABLE"/>
    (user_id,user_name,user_pwd,user_phone)
    values
    (#{user_id,jdbcType=INTEGER},#{user_name,jdbcType=VARCHAR},#{user_pwd,jdbcType=VARCHAR},#{user_phone,jdbcType=VARCHAR},)
  </insert>

<!--插入 变量名 可选择的-->
  <insert id="insertSelective" parameterType="com.tmf.mybatis.demo.model.User">
    insert into
    <include refid="BASE_TABLE"/>
    <trim prefix="(" suffix=")" suffixOverrides=",">
      <if test="userId!=null">
        user_id,
      </if>
      <if test="userName!=null">
        user_name,
      </if>
      <if test="userPwd!=null">
        user_pwd,
      </if>
      <if test="userPhone!=null">
        user_phone,
      </if>
    </trim>
    <trim prefix="VALUES(" suffix=")" suffixOverrides=",">
      <if test="userId!=null">
        #{user_id,jdbcType=INTEGER},
      </if>
      <if test="userName!=null">
        #{user_name,jdbcType=VARCHAR},
      </if>
      <if test="userPwd!=null">
        #{user_pwd,jdbcType=VARCHAR},
      </if>
      <if test="userPhone!=null">
        #{user_phone,jdbcType=VARCHAR},
      </if>
    </trim>
  </insert>

update 标签

属性同insert

示例

<!--根据Id进行更新-->
  <update id="updateById" parameterType="com.tmf.mybatis.demo.model.User">
    update
    <include refid="BASE_TABLE"/>
    set user_name=#{userName,jdbcType=VARCHAR},
    user_pwd = #{userPwd,jdbcType=VARCHAR},
    user_phone = #{userPhone,jdbcType=VARCHAR}
    where user_id = #{userId,jdbcType=INTEGER}
  </update>

<!--根据主键进行更新可选择的-->
  <update id="updateByIdSelective" parameterType="com.tmf.mybatis.demo.model.User">
    update
    <include refid="BASE_TABLE"/>
    <set>
      <if test="userPhone!=null">
        user_name=#{userName,jdbcType=VARCHAR},
      </if>
      <if test="userPwd!=null">
        user_pwd=#{userPwd,jdbcType=VARCHAR},
      </if>
      <if test="userPhone!=null">
        user_phone=#{userPhone,jdbcType=VARCHAR},
      </if>
    </set>
    where user_id = #{userId,jdbcType=INTEGER}
  </update>

delete 标签

属性同insert

示例

<delete id="deleteUser" parameterType="java.lang.Integer">
      delete from user
      where id = #{id}
</delete>

配置 Java 对象属性与查询结果集中列名对应关系

resultMap 标签

resultMap 标签的使用

  • 基本作用:
  • 建立 SQL 查询结果字段与实体属性的映射关系信息
  • 查询的结果集转换为 java 对象,方便进一步操作。
  • 将结果集中的列与 java 对象中的属性对应起来并将值填充进去
  • 注意:与 java 对象对应的列不是数据库中表的列名,而是查询后结果集的列名

示例

<!--查询返回值-->
  <resultMap id="userInfoMap" type="com.tmf.mybatis.demo.model.User">
    <id column="user_id" property="userId" jdbcType="INTEGER"/>
    <result column="user_name" property="userName" jdbcType="VARCHAR"/>
    <result column="user_pwd" property="userPwd" jdbcType="VARCHAR"/>
    <result column="user_phone" property="userPhone" jdbcType="VARCHAR"/>
  </resultMap>
<!--全查询 查询时resultMap引用该resultMap-->
  <select id="selectAll" resultMap="userInfoMap">
    select
    <include refid="BASE_COLUMN"/>
    from
    <include refid="BASE_TABLE"/>
  </select>

标签说明:

主标签:

  • id:该 resultMap 的标志
  • type:返回值的类名,此例中返回 Studnet 类

子标签:

  • id:用于设置主键字段与领域模型属性的映射关系,此处主键为 ID,对应 id。
  • result:用于设置普通字段与领域模型属性的映射关系

控制动态 SQL 拼接

if 标签

if 标签通常用于 WHERE 语句、UPDATE 语句、INSERT 语句中,通过判断参数值来决定是否使用某个查询条件、判断是否更新某一个字段、判断是否插入某个字段的值

示例

<if test="userPhone!=null">
        user_name=#{userName,jdbcType=VARCHAR},
</if>

foreach 标签

foreach 标签主要用于构建 in 条件,可在 sql 中对集合进行迭代。也常用到批量删除、添加等操作中。

示例

<delete id="deleteBatch">
     delete from user where id in
     <foreach collection="array" item="id" index="index" open="(" close=")" separator=",">
       #{id}
     </foreach>
   </delete>
  • 我们假如说参数为---- int[] ids = {1,2,3,4,5} ----那么打印之后的 SQL 如下:
delete form user where id in (1,2,3,4,5)

属性介绍:

  • collection:collection 属性的值有三个分别是 list、array、map 三种,分别对应的参数类型为:List、数组、map 集合。
  • item :表示在迭代过程中每一个元素的别名
  • index :表示在迭代过程中每次迭代到的位置(下标)
  • open :前缀
  • close :后缀
  • separator :分隔符,表示迭代时每个元素之间以什么分隔

choose 标签

有时候我们并不想应用所有的条件,而只是想从多个选项中选择一个。MyBatis 提供了 choose 元素,按顺序判断 when 中的条件出否成立,如果有一个成立,则 choose 结束。当 choose 中所有 when 的条件都不满则时,则执行 otherwise 中的 sql。类似于 Java 的 switch 语句,choose 为 switch,when 为 case,otherwise 则为 default。 if 是与(and)的关系,而 choose 是或(or)的关系。

示例

<select id="getStudentListChoose" parameterType="Student" resultMap="BaseResultMap">
    SELECT * from STUDENT WHERE 1=1
    <where>
        <choose>
            <when test="Name!=null and student!='' ">
                   AND name LIKE CONCAT(CONCAT('%', #{student}),'%')
            </when>
            <when test="hobby!= null and hobby!= '' ">
                    AND hobby = #{hobby}
            </when>
            <otherwise>
                    AND AGE = 15
            </otherwise>
        </choose>
    </where>
</select>

格式化输出

where 标签

当 if 标签较多时,这样的组合可能会导致错误。 如下:

<select id="getStudentListWhere" parameterType="Object" resultMap="BaseResultMap">
    SELECT * from STUDENT
        WHERE
        <if test="name!=null and name!='' ">
            NAME LIKE CONCAT(CONCAT('%', #{name}),'%')
        </if>
        <if test="hobby!= null and hobby!= '' ">
            AND hobby = #{hobby}
        </if>
</select>

当 name 值为 null 时,查询语句会出现 “WHERE AND” 的情况,解决该情况除了将"WHERE"改为“WHERE 1=1”之外,还可以利用 where 标签。这个“where”标签会知道如果它包含的标签中有返回值的话,它就插入一个‘where’。此外,如果标签返回的内容是以 AND 或 OR 开头的,则它会剔除掉。

<select id="getServiceListBySearch" resultType="java.util.Map">
        SELECT *
        FROM EHR_SERVICE_RECORD se
        LEFT JOIN EHR_PERSONAL_HEALTH_RECORD pe
        ON se.EHR_RCD_ID = pe.RCD_ID
        LEFT JOIN MBR_MEMBERSHIP_INFO me
        ON  pe.RCD_MBR_CARD= me.MBR_CARD
        <where>
            <if test="SearchVO.bespeakStartTime != null and '' != SearchVO.bespeakStartTime">
                se.RCD_SCHEDULE_TIME >= #{SearchVO.bespeakStartTime}
            </if>
        </where>
</select>

set 标签

没有使用 if 标签时,如果有一个参数为 null,都会导致错误。当在 update 语句中使用 if 标签时,如果最后的 if 没有执行,则或导致逗号多余错误。使用 set 标签可以将动态的配置 set 关键字,和剔除追加到条件末尾的任何不相关的逗号。

<update id="updateByIdSelective" parameterType="com.tmf.mybatis.demo.model.User">
    update
    <include refid="BASE_TABLE"/>
    set
    user_name=#{userName,jdbcType=VARCHAR},
    user_pwd=#{userPwd,jdbcType=VARCHAR},
    user_phone=#{userPhone,jdbcType=VARCHAR},
    where user_id = #{userId,jdbcType=INTEGER}
  </update>

使用 set+if 标签修改后,如果某项为 null 则不进行更新,而是保持数据库原值

<!--根据主键进行更新可选择的-->
  <update id="updateByIdSelective" parameterType="com.tmf.mybatis.demo.model.User">
    update
    <include refid="BASE_TABLE"/>
    <set>
      <if test="userPhone!=null">
        user_name=#{userName,jdbcType=VARCHAR},
      </if>
      <if test="userPwd!=null">
        user_pwd=#{userPwd,jdbcType=VARCHAR},
      </if>
      <if test="userPhone!=null">
        user_phone=#{userPhone,jdbcType=VARCHAR},
      </if>
    </set>
    where user_id = #{userId,jdbcType=INTEGER}
  </update>

trim 标签

trim 标签是一个格式化的标记,主要用于拼接 sql 的条件语句(前缀或后缀的添加或忽略),可以完成 set 或者是 where 标记的功能。

trim 属性介绍

  • prefix:前缀覆盖并增加其内容
  • suffix:后缀覆盖并增加其内容
  • prefixOverrides:前缀判断的条件
  • suffixOverrides:后缀判断的条件

update 中

<update id="updateByPrimaryKey" parameterType="Object">
        update student set
  <trim  suffixOverrides="," >
    <if test="name != null  ">
        NAME=#{name},
    </if>
    <if test="hobby != null  ">
        HOBBY=#{hobby},
    </if>
  </trim> where id=#{id}
</update>

如果 name 和 hobby 的值都不为空的话,会执行如下语句

update student set NAME='XX',HOBBY='XX' /*,*/ where id='XX'

select 中

<select id="selectByNameOrHobby" resultMap="BaseResultMap">
select * from student
<trim prefix="WHERE" prefixOverrides="AND | OR">
    <if test="name != null and name.length()>0"> AND name=#{name}
    </if>
    <if test="hobby != null and hobby.length()>0"> AND hobby=#{hobby}
    </if>
</trim>
</select>

如果 name 和 hobby 的值都不为空的话,会执行如下语句

select * from user WHERE /*and*/ name = ‘xx’ and hobby= ‘xx’

会为<trim>片段添加 “WHERE” 前缀,并忽略第一个 “and” ;

当然,避免出现“WHERE AND”还有其他方法,如下

<!--将where提取出来,并加上“1=1”的查询条件 -->
select * from student
where 1=1
<trim suffixOverrides=",">
   <if test="name != null and name != ''">
      and NAME = #{name}
   </if>
   <if test="hobby != null and hobby != ''">
      and HOBBY = #{hobby}
   </if>
</trim>

insert 中

<insert id="insertSelective" parameterType="com.tmf.mybatis.demo.model.User">
    insert into
    <include refid="BASE_TABLE"/>
    <trim prefix="(" suffix=")" suffixOverrides=",">
      <if test="userId!=null">
        user_id,
      </if>
      <if test="userName!=null">
        user_name,
      </if>
      <if test="userPwd!=null">
        user_pwd,
      </if>
      <if test="userPhone!=null">
        user_phone,
      </if>
    </trim>
    <trim prefix="VALUES(" suffix=")" suffixOverrides=",">
      <if test="userId!=null">
        #{user_id,jdbcType=INTEGER},
      </if>
      <if test="userName!=null">
        #{user_name,jdbcType=VARCHAR},
      </if>
      <if test="userPwd!=null">
        #{user_pwd,jdbcType=VARCHAR},
      </if>
      <if test="userPhone!=null">
        #{user_phone,jdbcType=VARCHAR},
      </if>
    </trim>
  </insert>

可以生成正确的 insert 语句

配置关联关系

association 标签

通常用于一对关系映射,一对一关系推荐使用唯一主外键关联,即两张表使用外键关联关系,由于是一对一关联,因此还需要给外键列增加 unique 唯一约束。

一对一关系映射

示例

  • 首先需要在对应实体帖子实体 Topic 中与帖子类型实体 TopicType 中建立对应的一对一关系
private TopicType topicType;
<association property="topicType" select="selectType" column="topics_type_id" javaType="com.tmf.bbs.pojo.Type"/>

属性说明

  • property:属性名
  • select:要连接的查询,也就是帖子类型查询语句
  • column:共同列
  • javaType:集合中元素的类型

多对一关系映射

示例

<!-- 多对一关联映射:association   -->
<association property="clazz" javaType="org.zang.domain.Clazz">
            <id property="id" column="id"/>
            <result property="code" column="code"/>
            <result property="name" column="name"/>
</association>
<!-- 根据id查询学生信息,多表连接,返回resultMap -->
  <select id="selectStudentById" parameterType="int" resultMap="studentResultMap">
      SELECT * FROM tb_clazz c,tb_student s
      WHERE c.id = s.clazz_id
       AND s.id = #{id}
  </select>
  • 使用<association…/>元素映射多对一的关联关系。因为<select id=“selectStudentById”…/>的 sql 语句是一条多表连接,关联 tb_clazz 表的同时查询了班级数据,所以<association…/>只是简单的装载数据。
  • 注意:在实际开发中,由于一对多关系通常映射为集合对象,而由于多方的数据量可能很大,所以通常使用懒加载;而多对一只是关联到一个对象,所以通常使用多表连接直接提取出数据。
collection 标签

通常用于一对多关系映射,或者多对多关系映射。数据库中一对多关系通常使用主外键关联,外键列应该在多方,即多方维护关系。

一对多关系映射

示例

  • 首先需要在对应实体帖子实体 Topic 中与帖子评论实体 TopicComment 中建立对应的一对多关系
private List<TopicComment> topicComment;
<collection property="topicComment" column="id" ofType="com.tmf.bbs.pojo.Comment" select="selectComment" fetchType="lazy" />

属性说明

  • property:属性名
  • column:共同列
  • ofType:集合中元素的类型
  • select:要连接的查询,也就是帖子评论查询实体
  • fetchType:lazy 表示懒加载,fatch 机制更多的是为了性能考虑正常情况下,一对多所关联的集合对象,都应该被设置成 lazy。

多对多关系映射

例如在一个购物系统中,一个用户可以有多个订单,这是一对多的关系;一个订单中可以有多种商品,一种商品也可以属于多个不同的订单,订单和商品就是多对多的关系。

示例

  • 订单实体和商品实体实体中需要指定对应关系
// 订单和商品是多对多的关系,即一个订单可以包含多种商品
class Order
private List<Product> products;
// 商品和订单是多对多的关系,即一种商品可以包含在多个订单中
class Product
private List<Order> orders;
  • 订单实体 mapper.xml 和商品实体 mapper.xml 需要指定关系映射
<!-- 一对多关联映射:collection   -->
<collection property="orders" javaType="ArrayList" column="id" ofType="org.zang.domain.User"
  select="org.zang.mapper.OrderMapper.selectOrderByUserId" fetchType="lazy">
  <id property="id" column="id"/>
  <result property="code" column="code"/>
  <result property="total" column="total"/>
</collection>
<!-- 多对多映射的关键:collection   -->
<collection property="products" javaType="ArrayList" column="oid" ofType="org.zang.domain.Product"
  select="org.zang.mapper.ProductMapper.selectProductByOrderId" fetchType="lazy">
  <id property="id" column="id"/>
  <result property="name" column="name"/>
  <result property="price" column="price"/>
  <result property="remark" column="remark"/>
</collection>

小结

  • * 对多关联映射:collection
  • * 对一关联映射:association
  • 一对多使用的都是 lazy(懒加载)

定义常量

sql 标签

当多种类型的查询语句的查询字段或者查询条件相同时,可以将其定义为常量,方便调用。为求<select>结构清晰也可将 sql 语句分解。

示例

<!--设置统一使用模板 表 列-->
<sql id="BASE_TABLE">
  t_user
</sql>
<!--查询字段-->
<sql id="BASE_COLUMN">
  user_id,user_name,user_pwd,user_phone
</sql>
<!-- 查询条件 -->
<sql id="Example_Where_Clause">
  where 1=1
  <trim suffixOverrides=",">
    <if test="userId != null and userId !=''">
      and user_id = #{userId}
    </if>
    <if test="userName != null and userName != ''">
      and user_name = #{userName}
    </if>
    <if test="userPwd != userPwd ">
      and user_pwd = #{userPwd}
    </if>
    <if test="userPhone != userPhone ">
      and user_phone = #{userPhone}
    </if>
  </trim>
</sql>

include 标签

用于引用定义的常量,也就是引用 sql 标签中的 id

示例

<!--查询 通过Id-->
<select id="selectById" resultMap="userInfoMap" parameterType="java.lang.Integer">
  select
  <include refid="BASE_COLUMN"/>
  from
  <include refid="BASE_TABLE"/>
  where user_id = #{userId,jdbcType=INTEGER}
</select>
<!--全查询-->
<select id="selectAll" resultMap="userInfoMap">
  select
  <include refid="BASE_COLUMN"/>
  from
  <include refid="BASE_TABLE"/>
</select>

<!--根据主键进行更新可选择的-->
<update id="updateByIdSelective" parameterType="com.tmf.mybatis.demo.model.User">
  update
  <include refid="BASE_TABLE"/>
  <set>
    <if test="userPhone!=null">
      user_name=#{userName,jdbcType=VARCHAR},
    </if>
    <if test="userPwd!=null">
      user_pwd=#{userPwd,jdbcType=VARCHAR},
    </if>
    <if test="userPhone!=null">
      user_phone=#{userPhone,jdbcType=VARCHAR},
    </if>
  </set>
  where user_id = #{userId,jdbcType=INTEGER}
</update>
<!--插入变量名  不选择的-->
<insert id="insert" parameterType="com.tmf.mybatis.demo.model.User">
  insert into
  <include refid="BASE_TABLE"/>
  (user_id,user_name,user_pwd,user_phone)
  values
  (#{user_id,jdbcType=INTEGER},#{user_name,jdbcType=VARCHAR},#{user_pwd,jdbcType=VARCHAR},#{user_phone,jdbcType=VARCHAR},)
</insert>

<!-- 根据条件删除 -->
<delete id="deleteByEntity" parameterType="java.util.Map">
  DELETE  FROM   student
  <include refid="Example_Where_Clause" />
</delete>

本文主要参考于Mybatis 全部标签与解释说明

结语

前面如有不正确的地方还希望大家多多指教,希望和志同道合的朋友一起学习,一起进步,先更新到这里,下次继续补充。