Mapper 文件中全部标签解释与说明
本文主要介绍的是 Mybatis 中对应实体的 mapper.xml 里面的标签说明
定义 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 全部标签与解释说明
结语
前面如有不正确的地方还希望大家多多指教,希望和志同道合的朋友一起学习,一起进步,先更新到这里,下次继续补充。