mybatis 级联查询

发布时间 2023-07-28 17:17:43作者: 黄光跃

一对一用 association 标签,一对多用 collection 标签。多对一就是一对一,只是站的角度不同

一对一

java 实体

@Data
public class SkuWithPrice{
    private Long id;
    
    private String code;
    
    private String name;
    
    // 一个 sku 只有一个价格
    private Price price;
    
    @Data
    public static class Price{
        private Long id;
    
        private BigDecimal price;

        private String currency;
    }
}

映射文件

<resultMap id="one2oneMap" type="com.study.mybatis.dto.SkuWithPrice">
    <id column="id" property="id" jdbcType="BIGINT"/>
    <result column="code" property="code" jdbcType="VARCHAR"/>
    <result column="name" property="name" jdbcType="VARCHAR"/>
    <association property="price" javaType="com.study.mybatis.dto.SkuWithPrice$Price">
        <!-- sku 表和 price 表都有 id,其中一个要取别名 -->
        <id column="priceId" property="id" jdbcType="BIGINT"/>
        <result column="price" property="price" jdbcType="DECIMAL"/>
        <result column="currency" property="currency" jdbcType="VARCHAR"/>
    </association>
</resultMap>
<select id="findOne" resultMap="one2oneMap">
    select a.id, a.code, a.name, b.id priceId, b.price, b.currency
    from t_sku a inner join t_price b on a.id = b.sku_id
</select>

一对多

java 实体

@Data
public class ItemWithSku{
    private Long id;
    
    private String code;
    
    private String name;
    
    // 一个商品多个 sku
    private List<Sku> skus;
    
    @Data
    public static class Sku{
        private Long id;
    
        private String code;

        private String name;
    }
}

映射文件

其实在一对一的基础上在映射文件中把 association 改为 collection 就行了,但是分页时候会有问题,因为这是一对多

<resultMap id="one2manyMap" type="com.study.mybatis.dto.ItemWithSku">
    <id column="id" property="id" jdbcType="BIGINT"/>
    <result column="code" property="code" jdbcType="VARCHAR"/>
    <result column="name" property="name" jdbcType="VARCHAR"/>
    <collection property="skus"
                column="id"
                javaType="ArrayList"
                ofType="com.study.mybatis.dto.ItemWithSku$Sku"
                select="getSkusByItemId"
    />
</resultMap>
<!-- 先查主表,以主表分页就不会有分页问题 -->
<select id="findItemAndSku" resultMap="one2manyMap">
    select a.id, a.code, a.name from t_item a
</select>
<!-- 再根据主表查询子表 -->
<select id="getSkusByItemId" resultType="com.study.mybatis.dto.ItemWithSku$Sku">
    <!-- #{id} 是主表传过来的 -->
    select a.id, a.code, a.name from t_sku a where a.item_id = #{id}
</select>