mybatis 实现多层级collection嵌套

 更新时间:2022年03月11日 08:39:36   作者:缥缈神  
这篇文章主要介绍了mybatis 实现多层级collection嵌套,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

mybatis多层级collection嵌套

json结构

第一步查询

第一层查询,将第一层的id传递到第二层当条件查询    column="id"

<resultMap id="BaseResultMapClass" type="com.kingyon.common.models.shortcut.ShortcutKeyClassBean">
    <id column="id" jdbcType="INTEGER" property="id"/>
    <result column="title" jdbcType="VARCHAR" property="title"/>
    <result column="img" jdbcType="VARCHAR" property="img"/>
    <result column="bgColor" jdbcType="VARCHAR" property="bgColor"/>
    <result column="describe" jdbcType="VARCHAR" property="describe"/>
    <result column="type" jdbcType="BIGINT" property="type"/>
    <collection property="functionBeans" ofType="com.kingyon.common.models.shortcut.ShortcutKeyFunctionBean"
                select="com.kingyon.core.repository.ShortcutKeyMapper.getShortcutKeyFunction" column="id">
 
    </collection>
</resultMap>
<select id="findShortcutKeyByClassID" resultMap="BaseResultMapClass">
    select * from t_shortcut_key_class where id=#{classID} ;
</select>

第二步查询

第二层查询,并将第二层的id传递到第三层当条件查询    column="funID"  是别名

<resultMap id="baseShortcutKey" type="com.kingyon.common.models.shortcut.ShortcutKeyFunctionBean">
    <id column="id" jdbcType="INTEGER" property="funID"/>
    <result column="classID" jdbcType="VARCHAR" property="classID"/>
    <result column="describe" jdbcType="VARCHAR" property="describe"/>
    <result column="sort" jdbcType="VARCHAR" property="sort"/>
    <result column="className" jdbcType="VARCHAR" property="className"/>
    <collection property="shortcutKeyBean" ofType="com.kingyon.common.models.shortcut.ShortcutKeyBean"
                select="com.kingyon.core.repository.ShortcutKeyMapper.getShortcutKey" column="funID">
 
    </collection>
</resultMap>
<select id="getShortcutKeyFunction" resultMap="baseShortcutKey">
    select fun.id as funID,fun.classID,fun.describe,fun.sort from t_shortcut_key_function  as fun where fun.classID=#{classID} order by sort DESC ;
</select>

第三步查询(第三层查询)

<resultMap id="shortcutKeyBean" type="com.kingyon.common.models.shortcut.ShortcutKeyBean">
    <result property="id" column="keyID"/>
    <result property="shortcut" column="shortcut"/>
    <result property="details" column="details"/>
</resultMap>
<select id="getShortcutKey" resultMap="shortcutKeyBean">
      select * from t_shortcut_key where funID=#{id};
</select>

其实蛮好理解的,就是查询一个,然后把条件传递下步继续查询。。。 使用时调第一层,也就是从高到底。

最后附实体截图,其实看json就可以了

第一层实体:

第二层实体:

第三层实体:

方式二(推荐)

<resultMap id="chapter" type="com.xx.xx.xx.xx.xxBean">
    <id column="id" property="id"/>
    <result column="name" property="name"/>
    <collection property="chapterChildBeans"
                ofType="com.xx.xx.mode.xx.xxBean">
        <id column="cId" property="id"/>
        <result column="cName" property="name"/>
    </collection>
</resultMap>
<select id="selectChapter" resultMap="chapter">
    SELECT c.id,c.name,cc.id as cId,cc.name as cName from t_chapter c,t_chapter_child cc WHERE c.id=cc.chapterID and c.subjectID=#{subjectID}
</select>

mybatis多层(三层)嵌套查询

java 实体描述

/**
 * <p>
 * 家庭表
 * </p>
 *
 * @author lohas
 */
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("t_family_info")
@ApiModel(value = "FamilyInfoEntity对象", description = "家庭表")
public class FamilyInfoEntity extends Model { 
    private static final long serialVersionUID = 1L; 
    @ApiModelProperty(value = "主键")
    @TableId(value = "id", type = IdType.INPUT)
    private String id;
 
    @ApiModelProperty(value = "家庭名称")
    private String familyName;
 
    @ApiModelProperty(value = "家庭头像url")
    private String headUrl;
 
    @ApiModelProperty(value = "国家")
    private String country;
 
    @ApiModelProperty(value = "城市")
    private String city;
 
    @ApiModelProperty(value = "地址")
    private String address;
 
    @ApiModelProperty(value = "经度")
    private BigDecimal longitude;
 
    @ApiModelProperty(value = "纬度")
    private BigDecimal latitude;
 
    @ApiModelProperty(value = "租户ID")
    private String tenantId;
 
    @ApiModelProperty(value = "是否删除(0:正常;低于0的数字:已删除)")
    private String deleteFlag;
 
    @ApiModelProperty(value = "创建人ID")
    private String creatorId;
 
    @ApiModelProperty(value = "创建时间")
    @JsonDeserialize(using = LocalDateTimeSerializerConfig.LocalDateTimeDeserializer.class)
    @JsonSerialize(using = LocalDateTimeSerializerConfig.LocalDateTimeSerializer.class)
    private LocalDateTime createTime;
 
    @ApiModelProperty(value = "更新人ID")
    private String updateId;
 
    @ApiModelProperty(value = "更新时间")
    @JsonDeserialize(using = LocalDateTimeSerializerConfig.LocalDateTimeDeserializer.class)
    @JsonSerialize(using = LocalDateTimeSerializerConfig.LocalDateTimeSerializer.class)
    private LocalDateTime updateTime;
 
}
/**
 * @author lohas
 * @description
 */
@Data
@ApiModel(value = "RoomDeviceInfoVo对象", description = "房间设备信息实体")
public class RoomDeviceInfoVo implements Serializable {
 
    @ApiModelProperty(value = "房间id")
    private String roomId;
 
    @ApiModelProperty(value = "房间名称")
    private String roomName;
 
    @ApiModelProperty(value = "设备数量")
    private Integer deviceNum;
 
    @ApiModelProperty(value = "设备信息列表")
    private List<String> deviceIds;
}
/**
 * @author lohas
 * @description
 */
@Data
@ApiModel(value = "FamilyRoomInfoVo对象", description = "家庭房间信息对象实例")
public class FamilyRoomInfoVo extends FamilyInfoEntity {
 
    @ApiModelProperty(value = "房间设备信息列表")
    private List<RoomDeviceInfoVo> roomDeviceInfoVoList;
}

mybatis 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.lohas.mapper.FamilyInfoMapper">
 
    <select id="getFamilyRoomInfoVoByUserId" resultMap="familyMap">
		SELECT *
		FROM (
             SELECT tfi.*,
                    trf."id"      AS r_room_id,  --要加上r因为columnPrefix="r_"(如果字段唯一,可以不加)
                    trf.room_name AS r_room_name, --要加上r因为columnPrefix="r_"
                    trd.device_id AS r_d_device_id --要加上r因为columnPrefix="r_",加上d因为columnPrefix="d_"
             FROM t_user_family tuf
                      LEFT JOIN t_family_info tfi ON tfi.ID = tuf.family_id
                      LEFT JOIN t_family_room tfr ON tuf.family_id = tfr.family_id
                      LEFT JOIN t_room_info trf ON tfr.room_id = trf.ID
                      LEFT JOIN t_room_device trd ON tfr.room_id = trd.room_id
             WHERE tuf.user_id = #{userId}
             ORDER BY tfi.create_time DESC
         ) AS fr,
         (
             SELECT trf."id"             AS r_room_id,  --要加上r因为columnPrefix="r_"
                    COUNT(trd.device_id) AS r_device_num  --要加上r因为columnPrefix="r_"
             FROM t_user_family tuf
                      LEFT JOIN t_family_info tfi ON tfi.ID = tuf.family_id
                      LEFT JOIN t_family_room tfr ON tuf.family_id = tfr.family_id
                      LEFT JOIN t_room_info trf ON tfr.room_id = trf.
                 ID
                      LEFT JOIN t_room_device trd ON tfr.room_id = trd.room_id
             WHERE tuf.user_id = #{userId}
             GROUP BY trf."id"
         ) AS rd
		WHERE fr.r_room_id = rd.r_room_id
	</select>
 
	<resultMap id="familyMap" type="com.lohas.vo.FamilyRoomInfoVo">
		<!-- 一层: 家庭信息-->
		<id column="id" jdbcType="VARCHAR" property="id"/>
		<result column="family_name" jdbcType="VARCHAR" property="familyName"/>
		<result column="head_url" jdbcType="VARCHAR" property="headUrl"/>
		<result column="country" jdbcType="VARCHAR" property="country"/>
		<result column="city" jdbcType="VARCHAR" property="city"/>
		<result column="address" jdbcType="VARCHAR" property="address"/>
		<result column="longitude" jdbcType="NUMERIC" property="longitude"/>
		<result column="latitude" jdbcType="NUMERIC" property="latitude"/>
		<result column="delete_flag" jdbcType="CHAR" property="deleteFlag"/>
		<result column="creator_id" jdbcType="VARCHAR" property="creatorId"/>
		<result column="create_time" jdbcType="TIMESTAMP" property="createTime"/>
		<result column="update_id" jdbcType="VARCHAR" property="updateId"/>
		<result column="update_time" jdbcType="TIMESTAMP" property="updateTime"/>
		<result column="tenant_id" jdbcType="VARCHAR" property="tenantId"/>
		<!-- 如果字段唯一,可以不加columnPrefix="r_"-->
		<collection property="roomDeviceInfoVoList" columnPrefix="r_" resultMap="roomMap"/>
	</resultMap>
 
	<resultMap id="roomMap" type="com.lohas.vo.RoomDeviceInfoVo">
		<!-- 二层: 房间信息-->
		<result column="room_id" jdbcType="VARCHAR" property="roomId"/>
		<result column="room_name" jdbcType="VARCHAR" property="roomName"/>
		<result column="device_num" jdbcType="VARCHAR" property="deviceNum"/>
		<!-- 如果字段唯一,可以不加columnPrefix="d_"-->
		<collection property="deviceIds" columnPrefix="d_" resultMap="deviceMap"/>
	</resultMap>
 
	<resultMap id="deviceMap" type="string">
		<!-- 三层: 设备信息-->
		<result column="device_id" jdbcType="VARCHAR"/>
	</resultMap>
 
</mapper>

调用方法

public interface FamilyInfoMapper extends BaseMapper<FamilyInfoEntity> { 
    List<FamilyRoomInfoVo> getFamilyRoomInfoVoByUserId(@Param("userId") String userId);   
}

注意总结

如果你的字段唯一,columnPrefix="r_" 和 columnPrefix="d_",可以不加,如果你加上了columnPrefix记得在字段上拼接上,否则查询不出数据,拼接要有前后顺序拼接例如:

<collection property="roomDeviceInfoVoList" columnPrefix="r_" resultMap="roomMap"/>
<collection property="deviceIds" columnPrefix="d_" resultMap="deviceMap"/>
r_d_device_id(要加上r因为roomMap columnPrefix="r_",加上d因为deviceMap columnPrefix="d_")

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • java单向链表的实现实例

    java单向链表的实现实例

    java单向链表的实现实例。需要的朋友可以过来参考下,希望对大家有所帮助
    2013-10-10
  • Java深入分析动态代理

    Java深入分析动态代理

    动态代理指的是,代理类和目标类的关系在程序运行的时候确定的,客户通过代理类来调用目标对象的方法,是在程序运行时根据需要动态的创建目标类的代理对象。本文将通过案例详细讲解一下Java动态代理的原理及实现,需要的可以参考一下
    2022-07-07
  • springboot如何获取application.yml里值的方法

    springboot如何获取application.yml里值的方法

    这篇文章主要介绍了springboot如何获取application.yml里的值,文章围绕主题相关自资料展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-04-04
  • 在Java中为日期增加一天的多种方法

    在Java中为日期增加一天的多种方法

    这篇文章主要给大家介绍了关于如何在Java中为日期增加一天的多种方法,在JAVA业务代码中,经常会遇到通过指定时间,增加指定天数的业务需求,需要的朋友可以参考下
    2023-07-07
  • Java客户端服务端上传接收文件实现详解

    Java客户端服务端上传接收文件实现详解

    这篇文章主要介绍了Java客户端服务端上传接收文件实现详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-07-07
  • java递归实现树形结构数据完整案例

    java递归实现树形结构数据完整案例

    递归算法的代码比较简洁,可读性较好;但是在实际的业务处理中会出现多次的重复调用,如果处理不好,很容易出现StackOverflowError报错,这篇文章主要给大家介绍了关于java递归实现树形结构数据的相关资料,需要的朋友可以参考下
    2023-04-04
  • 探索Java中的equals()和hashCode()方法_动力节点Java学院整理

    探索Java中的equals()和hashCode()方法_动力节点Java学院整理

    这篇文章主要介绍了探索Java中的equals()和hashCode()方法的相关资料,需要的朋友可以参考下
    2017-05-05
  • 剑指Offer之Java算法习题精讲链表与数组专项训练

    剑指Offer之Java算法习题精讲链表与数组专项训练

    跟着思路走,之后从简单题入手,反复去看,做过之后可能会忘记,之后再做一次,记不住就反复做,反复寻求思路和规律,慢慢积累就会发现质的变化
    2022-03-03
  • 支付宝二面:使用 try-catch 捕获异常会影响性能吗(推荐)

    支付宝二面:使用 try-catch 捕获异常会影响性能吗(推荐)

    这篇文章主要介绍了支付宝二面:使用 try-catch 捕获异常会影响性能吗,需要注意的是,JVM 中 异常处理的catch语句不再由字节码指令来实现(很早之前通过 jsr和 ret指令来完成,需要的朋友可以参考下
    2023-03-03
  • MybatisPlus关联查询的完美实现方案

    MybatisPlus关联查询的完美实现方案

    我们在项目开发的时候,难免会遇到连表查询的操作,所以下面这篇文章主要给大家介绍了关于MybatisPlus关联查询的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2021-12-12

最新评论