mybatis xml 从地区的父类子类,学习association&collection的区别,入门必看

一、前言

做了多年的java开发,突然想写一系列关于mybatis xml的 association & collection

下面的图片为本文讲解的重点
在这里插入图片描述

二、association & collection的区别

两个都是在ResultMap标签中使用的

MyBatis 创建时的一个思想是:数据库不可能永远是你所想或所需的那个样子。 我们希望每个数据库都具备良好的第三范式或 BCNF 范式,可惜它们并不都是那样。 如果能有一种数据库映射模式,完美适配所有的应用程序,那就太好了,但可惜也没有。 而 ResultMap 就是 MyBatis 对这个问题的答案。

  • association – 一个复杂类型的关联;许多结果将包装成这种类型
    嵌套结果映射 – 关联可以是 resultMap 元素,或是对其它结果映射的引用

  • collection – 一个复杂类型的集合
    嵌套结果映射 – 集合可以是 resultMap 元素,或是对其它结果映射的引用

在开发中:

  1. 针对关联属性是单对象(非集合类型)类型,使用 association 元素,通常直接使用多表查询操作。
  2. 针对关联属性是集合对象类型,使用 collection 元素,通常使用额外 SQL 处理,配置延迟加载。

2.1 核心代码

<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="com.cancan.mp.entity.Region">
    <id column="id" property="id" />
    <result column="region_name" property="regionName" />
    <result column="parent_id" property="parentId" />
    <result column="rp_region_name" property="parentName"/>

    <!--列出地区的父类-->
    <association property="parent" javaType="com.cancan.mp.entity.Region">
        <id column="rp_id" property="id" />
        <result column="rp_region_name" property="regionName" />
        <result column="rp_parent_id" property="parentId" />
    </association>
    
    <!--根据父类id,查出子类id-->
    <collection property="children" select="com.cancan.mp.mapper.RegionMapper.selectByCode" column="id"/>

</resultMap>

2.2 数据库的数据

在这里插入图片描述

2.3 id找出该id对应的parent_id和 children的集合 获取请求结果

GET http://localhost:8081/region/get?id=440100

{
    
    
  "id": 440100,
  "regionName": "广州市",
  "parentId": 440000,
  "parentName": "广东省",
  "parent": {
    
    
    "id": 440000,
    "regionName": "广东省",
    "parentId": 0,
    "parentName": null,
    "parent": null,
    "children": null
  },
  "children": [
    {
    
    
      "id": 440101,
      "regionName": "市辖区",
      "parentId": 440100,
      "parentName": null,
      "parent": null,
      "children": null
    },
    {
    
    
      "id": 440183,
      "regionName": "增城市",
      "parentId": 440100,
      "parentName": null,
      "parent": null,
      "children": null
    },
    {
    
    
      "id": 440184,
      "regionName": "从化市",
      "parentId": 440100,
      "parentName": null,
      "parent": null,
      "children": null
    }
  ]
}

三、具体案例

3.1 数据库的表

CREATE TABLE `region` (
  `id` int(11) NOT NULL COMMENT '主键',
  `region_name` varchar(40) DEFAULT NULL COMMENT '地区名字',
  `parent_id` int(11) DEFAULT NULL COMMENT '父类id',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='地区表';

3.2 实体类

@Data
@EqualsAndHashCode(callSuper = false)
@TableName("region")
public class Region implements Serializable {
    
    

    private static final long serialVersionUID = 1L;

    /**
     * 主键
     */
    @TableId(value = "id", type = IdType.INPUT)
    private Integer id;

    /**
     * 地区名字
     */
    @TableField("region_name")
    private String regionName;

    /**
     * 父类id
     */
    @TableField("parent_id")
    private Integer parentId;

    /**
     * 父类的名字
     */
    @TableField(exist = false)
    private String parentName;

    /**
     * 父类
     */
    @TableField(exist = false)
    private Region parent;

    /**
     * 子类
     */
    @TableField(exist = false)
    private List<Region> children;

}

3.3 mapper 和 mapper.xml

public interface RegionMapper extends BaseMapper<Region> {
    
    

    Region getRegion(@Param("code") Integer id);
}
<?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.cancan.mp.mapper.RegionMapper">

    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.cancan.mp.entity.Region">
        <id column="id" property="id" />
        <result column="region_name" property="regionName" />
        <result column="parent_id" property="parentId" />
        <result column="rp_region_name" property="parentName"/>

        <!--列出地区的父类-->
        <association property="parent" javaType="com.cancan.mp.entity.Region">
            <id column="rp_id" property="id" />
            <result column="rp_region_name" property="regionName" />
            <result column="rp_parent_id" property="parentId" />
        </association>

        <!--根据父类id,查出子类id-->
        <collection property="children" select="com.cancan.mp.mapper.RegionMapper.selectByCode" column="id"/>

    </resultMap>

    <!-- 通用查询结果列 -->
    <sql id="Base_Column_List">
        id, region_name, parent_id
    </sql>
    <select id="getRegion" resultMap="BaseResultMap">
        select
         r.id,
         r.region_name,
         r.parent_id,
         rp.id rp_id,
         rp.region_name rp_region_name,
         rp.parent_id rp_parent_id
        from region r
        left join region rp
        on r.parent_id = rp.id
        where r.id = #{code}

    </select>

    <select id="selectByCode" resultType="com.cancan.mp.entity.Region">
        select
        <include refid="Base_Column_List"/>
        from region
        where parent_id = #{id}
    </select>

</mapper>

猜你喜欢

转载自blog.csdn.net/qq_34168515/article/details/111113408