MyBatis 映射文件标签

MyBatis 映射文件标签

在这里插入图片描述

映射文件要和接口文件名称相同。

ORM(Object Relationship Mapping)对象关系映射。

对象代表 Java 实体类对象,关系代表关系型数据库,映射代表二者之间的对应关系。

下面将对 MyBatis XML 映射文件的常用标签进行总结:

一、定义SQL语句

​ 共有4个标签,分别是insert、delete、update、select,对应增删改查。其中,select 标签的使用频率最高。具体使用如下:

Mapper 层接口定义方法如下:

public interface StudentMapper {
    
    
    Student findById(Integer id);
    List<Student> findAll();
}

Mapper.XML 映射文件如下:

<?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.exercise.dao.StudentMapper">
    <select id="fingById" resultType="com.exercise.entity.Student">
        <!-- Mybatis负责把SQL语句中的#{}部分替换成“?”占位符,在#{}内部还是要声明一个见名知意的名称 -->
        select * from t_student where id = #{id}
    </select>
    
    <select id="findAll" resultType="com.exercise.entity.Student">
       select * from user
    </select>
</mapper>

说明:

  • mapper 是根标签,namespace 属性设置为接口的全类名。
  • 标签中的 id 属性是接口方法的方法名,id 是唯一的,即标记一条 SQL 语句。
  • 标签中的 resultType 属性是接口方法的返回值类型,格式为全类名,如果是集合类型,则写其泛型的全类名。
  • 标签中的 parameterType 属性是接口方法的参数类型,格式为全类名,如果是集合类型,则写其泛型的全类名。
  • 参数/返回值类型为基本数据类型/包装类/String等类型时,我们可以写全类名,也可以写别名。MyBatis 内置的类型别名如下:
映射的类型 别名 映射的类型 别名
byte _byte String string
long _long Byte byte
short _short Long long
int _int Short short
int _integer Integer integer\int
double _double Double double
float _float Float float
boolean _boolean Boolean boolean
Map map Date date
HashMap hashmap BigDecimal decimal
List list BigDecimal bigdecimal
ArrayList arraylist Object obkect
Collection collection Iterator iterator

二、自定义映射关系

​ MyBatis 可以将数据库结果集封装到对象中,是因为结果集的列名和对象属性名相同。当 Entity 属性名和数据库列名不一致时,MyBatis 无法自动完成映射

关系。此时有两种解决方案:

  1. SQL 语句的查询字段起与 Entity 属性相同的别名。
  2. 自定义映射关系,使用<resultMap>标签定义对应关系,再在后面的SQL语句中引用这个对应关系

实际开发中使用第二种方式居多,具体如下:

<resultMap id="selectStudentMap" type="com.exercise.entity.Student">
    <id column="id" property="studentId"/>
    <result column="name" property="studentName"/>
    <result column="class" property="studentClass"/>
</resultMap>

<select id="selectStudent" resultMap="selectStudentMap">
    select id,name,class from t_student where id=#{id}
</select>

说明:

  • resultMap 标签中的 id 属性为自定义映射名,type 属性为自定义映射的对象(实际开发中一般为一个 DTO 或者 VO)。
  • id 标签设置主键列和主键属性之间的对应关系,column 属性代表数据库字段名,property 属性代表 Java 实体类属性名。
  • result 标签设置普通字段和 Java 实体类属性之间的关系,column 和 property 属性与 id 标签一致。

三、动态SQL拼接

1. if 标签

​ 使用<if>标签,让我们可以有选择的加入 SQL 语句的片段。标签内的Sql片段在满足条件后才会添加,具体如下:

<select id="selectByCondition" parameterType="com.exercise.entity.Student" resultType="com.exercise.entity.Student">
   	select * from t_student
    <where>
        <if test="id != null">
           id = #{id}
        </if>
        <if test="name != null and name.length() != 0">
           and name like concat('%',#{name},'%')
        </if>
        <if test="class != null and class.length() != 0">
           and class = #{class}
        </if>
    </where>
</select>

说明:

  • if 标签中的 test 属性代表条件,满足则加入 SQL 片段,反之则不加入。
  • if 中的条件可以直接通过属性名获取参数 Entity 的属性值,并且该值可以调用方法,例如 String.length(),不能访问数据库表的字段。
  • if 中的条件不能使用 &&/|| ,而应该使用 and/or。

2. foreach 标签(重要)

<foreach>标签可以遍历集合或者数组,在实际开发中非常实用。它主要有以下属性:

  • collection 属性:遍历的集合对象
  • item 属性:表示本次遍历获取的元素(设置名字,便于后面引用),遍历 List、Set、数组时表示每项元素,遍历 Map 时表示键值对的
  • index 属性:遍历 List、数组时表示遍历的索引,遍历 Map 时表示键值对的
  • separator 属性:遍历每项元素间的分隔符。
  • open 属性:拼接字符串的前缀。
  • close 属性:拼接字符串的后缀。

此处放一个遇见的实际场景,单表查询(表、查询字段、查询字段值、附加条件都为动态获取),具体例子如下:

Dao 层接口方法如下:

/**
 * 单表查询
 * @param tableName                 表名
 * @param queryPrimaryKeyList       查询主键集合(注:设计集合的形式是因为还有多表联查)
 * @param queryPrimaryKeyValueList  查询主键集合(附带value)
 * @param queryFieldList            查询字段集合(注:查询字段里面不包含查询主键)
 * @param extraFieldList            附加条件集合
 * @return
 */
List<Map<String,Object>> queryDataResultSingleTable(@Param("tableName") String tableName,
                                                    @Param("queryPrimaryKeyList") List<String> queryPrimaryKeyList,
                                                    @Param("queryPrimaryKeyValueList") List<Map<String, Object>> queryPrimaryKeyValueList,
                                                    @Param("queryFieldList") List<String> queryFieldList,
                                                    @Param("extraFieldList") List<ExtraFieldDTO> extraFieldList);

Mapper.XML 映射文件如下:

<select id="queryDataResultSingleTable" resultType="map">
    SELECT
    <foreach collection="queryPrimaryKeyList" item="queryPrimaryKey" index="index" separator=",">
        ${queryPrimaryKey}
    </foreach>,
    <foreach collection="queryFieldList" item="queryField" index="index" separator=",">
        ${queryField}
    </foreach>
    FROM
    ${tableName}
    <where>
        <foreach collection="queryPrimaryKeyValueList" item="queryPrimaryKey" >
            <foreach collection="queryPrimaryKey.entrySet()" item="value" index="key">
                OR ${key} = #{value}
            </foreach>
        </foreach>
        <if test="extraFieldList!= null and extraFieldList.size()>0 ">
            <foreach collection="extraFieldList" item="extraField">
                <foreach collection="extraField.entrySet()" item="value" index="key">
                    AND ${key} like concat('%',#{value,jdbcType=VARCHAR},'%')
                </foreach>
            </foreach>
        </if>
    </where>
</select>

3. choose/when/otherwise 标签

​ 这三个标签表示多条件分支,即在多个分支条件中,仅执行一个。类似于 Java 中的 switch…case 语句,<choose>类似于 switch 关键字,<when>类似于 case 关键字,<otherwise> 类似于 default 关键字。执行流程如下:

  • 从上到下依次进行条件判断。
  • 判断到第一个满足条件的分支会被执行。
  • 被执行后后面的分支都不会执行。
  • 如果所有的 when 分支都不满足,即执行 otherwise 分支中的语句。

具体举例如下:

<!-- 含义为名字长度<3时使用模糊查询,名字长度>=3并且<5时使用精确查询,否则查询id为1的用户 -->
<select id="selectByCondition" resultType="com.exercise.entity.Student" parameterType="com.exercise.entity.Student">
   select * from t_student
    <where>
        <choose>
            <when test="name.length()&lt; 3">
               name like concat('%',#{value},'%')
            </when>
            <when test="name.length()&lt; 5">
                name = #{name}
            </when>
            <otherwise>
               	id = 1
            </otherwise>
        </choose>
    </where>
</select>

说明:在 MyBatis 映射文件中尽量不要使用一些特殊字符,如:<,>等。我们可以使用符号的实体来表示,具体如下:

符号 实体
< &lt;
> &gt;
& &amp;
&apos;
‘’ &quot;

四、格式化输出

1. where 标签

<where>标签可以自动去掉标签体内多余的 and 和 or 。此标签一般配合 if 标签使用,试想一下,如果我们使用 if 标签,就需要加入 where 关键字,当所有的 if 条件都不满足或者从第二个条件开始满足,这时我们输出的 SQL 语句就是错误的。由于在前面标签的举例中一直在使用 where 标签,此处就不做具体举例了。

2. set 标签

​ 在实际开发中,对于一个实体类对象进行更新,往往不是更新所有字段,而是更新用户更改的一部分字段。<set>标签用在 update 语句中,借助 <if>标签,可以只对有具体值的字段进行更新。<set>标签会自动添加 set 关键字,并且动态去掉两端多余的逗号。具体举例如下:

<update id="updateById" parameterType="com.exercise.entity.Student">
   update user
    <set>
        <if test="name != null and name.length() > 0">
           name = #{name},
        </if>
        <if test="class != null and class.length() > 0">
           class = #{class},
        </if>
    </set>
    <where>
       	id = #{id}
    </where>
</update>

3. trim 标签

<trim>标签可以控制条件部分两端是否包含某些字符,它主要有以下属性:

  • prefix 属性:指定要动态添加的前缀
  • suffix 属性:指定要动态添加的后缀
  • prefixOverrides 属性:指定要动态去掉的前缀,使用"|"分隔有可能的多个值
  • suffix Overrides 属性:指定要动态去掉的后缀,使用"|"分隔有可能的多个值

五、配置关联关系

1. association 标签

​ 使用<association>标签可以配置一对一关联关系,它有以下属性,具体如下:

  • property 属性:引用时使用的属性名
  • javaTyoe 属性:对应的全类名

具体举例如下:

<resultMap id="studentMap" type="com.exercise.entity.Student">
    <id column="id" property="id"></id>
    <result column="name" property="name"></result>
    <!-- 一对一对象列 property:属性名 javaType:对象类型-->
    <association property="class" javaType="com.exercise.entity.Class">
        <id column="class_id" property="classId"></id>
        <result column="class_name" property="className"></result>
    </association>
</resultMap>

<!-- 多表查询,级联查询学生和其班级 -->
<select id="findAll" resultMap="studentMap">
   select * from t_student left join t_class on student.classId = class.class_id
</select>

2. collection 标签

​ 使用<collection>标签可以配置一对多关联关系,它有一下属性,具体如下:

  • property 属性:关联“多”的一端的属性名
  • ofTyoe 属性:集合属性中元素的类型

具体举例如下:

<resultMap id="classesMap" type="com.exercise.entity.Class">
    <id column="class_id" property="classId"></id>
    <result column="class_name" property="className"></result>
    <!-- 集合列 property:属性名 ofType:集合的泛型 -->
    <collection property="studentList" ofType="com.exercise.entity.Student">
        <id column="id" property="id"></id>
        <result column="name" property="name"></result>
    </collection>
</resultMap>

<!-- 多表查询,级联查询班级和它的学生 -->
<select id="selectAllStudent" resultMap="classesMap">
    select * from t_class left join t_student on class.class_id = student.classId;
</select>

六、定义常量及引用

<sql>标签可以用来定义可重用的 SQL 片段,然后通过 <include>标签引入该片段。具体使用如下:

<sql id="selectAllField">
   	select id as studentId, name as studentName
</sql>

<select id="selectById" resultType="com.exercise.entity.Student">
    <include refid="selectAllField"></include>
   	from t_student where id = #{id}
</select>

猜你喜欢

转载自blog.csdn.net/m0_53067943/article/details/128320027
今日推荐