MyBatis XML文件详解

定义文件版本、编码、规范

通常写在xml文件开头

1
2
<?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">

定义命名空间

定义这个xml文件对应到哪一个mapper接口文件上,namespace 建议写全路径名

正文部分可以定义各种 resultMap 和 CRUD的SQL语句

1
2
3
<mapper namespace="com.jd.y.insight.domain.repository.mybatis.mapper.master.ext.IndustryCompanyRelationExtMapper">
<!-- 正文 -->
</mapper>

定义resultMap

resultMap,自定义的结果映射,通常写在正文的开始部分

  • id : 标识了这个resultMap的名称
  • type:标识了这个resultMap映射的实体类是谁
1
2
3
<resultMap id="BaseResultMap" type="实体类的全路径名">
<!-- 定义列名和实体类属性名的映射关系 -->
</resultMap>

主键描述:

1
<id column="id" jdbcType="BIGINT" property="id"/>

列名和实体类的映射描述:

1
2
3
4
<result column="batch_id" jdbcType="VARCHAR" property="batchId"/>
<result column="......." jdbcType="......" property="......"/>
......
<result column="yn" jdbcType="INTEGER" property="yn"/>

完整示例代码:

1
2
3
4
5
6
7
<resultMap id="BaseResultMap" type="实体类的全路径名">
<id column="id" jdbcType="BIGINT" property="id"/>
<result column="batch_id" jdbcType="VARCHAR" property="batchId"/>
<result column="......." jdbcType="......" property="......"/>
......
<result column="yn" jdbcType="INTEGER" property="yn"/>
</resultMap>

类中包含了内部类的情况:

完整示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<resultMap id="FullMappingResultMap" type="com.jd.y.insight.domain.category.pojo.entity.CategoryFullMappingEntity">
<!-- 非内部类部分 开始 -->
<id column="id" jdbcType="BIGINT" property="id"/>
......
<result column="......" jdbcType="......" property="......"/>
......
<result column="yn" jdbcType="INTEGER" property="yn"/>
<!-- 非内部类部分 结束 -->
<!-- 内部类1 开始 -->
<collection property="内部类的名称1" ofType="内部类1的全路径名"
columnPrefix="opponent_">
<result column="id1" jdbcType="INTEGER" property="id1"/>
......
<result column="......" jdbcType="......" property="......"/>
......
<result column="yn1" jdbcType="INTEGER" property="yn1"/>
</collection>
<!-- 内部类1 结束 -->
<!-- 内部类2 开始 -->
<collection property="内部类的名称2" ofType="内部类2的全路径名"
columnPrefix="opponent_">
<result column="id2" jdbcType="INTEGER" property="id2"/>
......
<result column="......" jdbcType="......" property="......"/>
......
<result column="yn2" jdbcType="INTEGER" property="yn2"/>
</collection>
<!-- 内部类2 结束 -->
<!-- 内部类3 开始 -->
<collection property="内部类的名称3" ofType="内部类3的全路径名"
columnPrefix="opponent_">
<result column="id3" jdbcType="INTEGER" property="id3"/>
......
<result column="......" jdbcType="......" property="......"/>
......
<result column="yn3" jdbcType="INTEGER" property="yn3"/>
</collection>
<!-- 内部类3 结束 -->
</resultMap>

定义SQL替换语句块

所谓的替换语句块,是指常用的SQL语句块,单独定义,然后每次使用的时候调用这块SQL语句,相当于使用事先定义好的SQL语句块插入到指定的SQL语句内部,拼接成完整SQL语句

示例1 - 自定义常用的查询字段:

1
2
3
4
<sql id="Base_Column_List">
<!-- 想要查询的各种列名 -->
column1, column2, ...., columnN
</sql>

示例2 - 自定义查询条件:

  • 可以使用组合来动态拼接查询条件
  • 可以使用<foreach …>循环拼接查询条件
1
2
3
4
5
6
7
8
9
10
11
12
<sql id="queryBaseCondition">
<if test="类的属性1 != null and 类的属性2 == 1">
and 列名1 > 0
</if>
......
<if test="batchChooseBrandList != null and batchChooseBrandList.size() > 0">
and 列名2 in
<foreach collection="入参是个列表" item="item" open="(" separator="," close=")">
#{item}
</foreach>
</if>
</sql>

定义SQL语句

INSERT

  • id :必须和Mapper接口定义的方法(DAO层方法)同名

  • parameterType : 入参类型,一般写类的全限定名,如果是Java自带的类如String,就写java.lang.String,自定义的类就写自定义类的全限定名

  • resultType:出参类型,同上

  • resultMap:和resultType二选一,是之前自己定义好的映射实体

  • useGeneratedKeys=”true” keyProperty=”id” : 用于insert语句,插入新数据成功时返回i

  • 自动生成主键:

    1
    2
    3
    4
     <!-- 自动生成主键 -->
    <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Long">
    SELECT LAST_INSERT_ID()
    </selectKey>

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<insert id="DAO层接口名" parameterType="Query类的全路径名" useGeneratedKeys="true" keyProperty="id">
<selectKey keyProperty="id" order="AFTER" resultType="java.lang.Long">
SELECT LAST_INSERT_ID()
</selectKey>
insert into industry_datadate
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="id != null">
id,
</if>
<if test="batchId != null">
batch_id,
</if>
......
<if test="yn != null">
yn,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="id != null">
#{id},
</if>
<if test="batchId != null">
#{batchId,jdbcType=VARCHAR},
</if>
......
<if test="yn != null">
#{yn,jdbcType=INTEGER},
</if>
</trim>
ON DUPLICATE KEY UPDATE
......
yn = VALUES(yn)
</insert>

UPDATE

语法上和INSERT语句相同,使用:

1
2
3
<update ...>
...
</update>

DELETE

语法上和INSERT语句相同,使用:

1
2
3
<delete ...>
...
</delete>

SELECT

语法上和INSERT语句相同,使用:

1
2
3
<select ...>
...
</select>