mybatis 实现多层级collection嵌套

目录
  • mybatis多层级collection嵌套
    • json结构
    • 第一步查询
    • 第二步查询
    • 第三步查询(第三层查询)
    • 最后附实体截图,其实看json就可以了
    • 方式二(推荐)
  • mybatis多层(三层)嵌套查询
    • java实体描述
    • mybatisxml
    • 调用方法
    • 注意总结

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_")

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

(0)

相关推荐

  • MyBatis 配置之集合的嵌套方式

    目录 MyBatis 配置之集合的嵌套 前言介绍 代码示例 外部引用 小结一下吧 MyBatis 集合.集合嵌套查询 集合 集合的嵌套查询 集合的嵌套结果 MyBatis 配置之集合的嵌套 前言介绍 在一些查询结果包装类中,包含一些 List 集合属性,使用 collection 标签可以声明该 List 集合中属性的类型,便于 MyBatis 对包装类中的集合类型属性进行映射. 代码示例 例如商城,取出某一个商品信息以及该商品的评价列表,其中商品包装类 Product 的定义代码如下: pac

  • mybatis多层嵌套resultMap及返回自定义参数详解

    1.两层嵌套,一个list中加另外一个list data:[ {a:123,b:456,c:[{d:7,e:8}]} ] xml文件定义的sql select * from zhy z LEFT JOIN wl w on z.id = w.zid resultMap可以定义: <resultMap id="zhyResultMap" type="zhy的doman实体" extends="zhy自动生成的BaseResultMap">

  • 解决mybatis 中collection嵌套collection引发的bug

    我就废话不多说了,大家还是直接看代码吧~ <resultMap id="ParentMap" type="org.example.mybatis.Parent"> <id column="Id" jdbcType="VARCHAR" property="id" /> <result column="Name" jdbcType="VARCHAR&q

  • Mybatis中Collection集合标签的使用详解

    mybatis简单的CURD就不用多说了,网上相关博客文档一大堆.分析一下Mybatis里面的collection聚集查询. 假设一个班级有多名学生为例,通过班级号查询出该班级的信息,和班级里面的所有学生的信息,一般的做法就是通过班级号把班级的信息查询出来,再通过班级ID号把该班级里面的所有学生查询出来,我们不用这种通用的方法 1.班级实体类可以定义为这样: import java.util.List; public class ClazzEntity { private int clazzID

  • mybatis 实现多层级collection嵌套

    目录 mybatis多层级collection嵌套 json结构 第一步查询 第二步查询 第三步查询(第三层查询) 最后附实体截图,其实看json就可以了 方式二(推荐) mybatis多层(三层)嵌套查询 java实体描述 mybatisxml 调用方法 注意总结 mybatis多层级collection嵌套 json结构 第一步查询 第一层查询,将第一层的id传递到第二层当条件查询    column="id" <resultMap id="BaseResultMa

  • mybatis使用collection嵌套查询的实现

    在开发中,可能会遇到一对多的关系,这个时候,一条sql语句就难以胜任这个任务了.只能先执行一条sql,然后根据返回的结果,再做一次sql关联查询,这个时候,使用mybatis的collection就可以实现. 如果第一次查询返回的是一个list集合,那么,后续的查询就是一个for循环.所以不使用collection的做法,在java语言中,就要分两次查询.一般而言,我们的列表查询都是分页查询,所以集合数据不会太大,第二次for循环查询效率还好. 下面介绍mybatis使用collection嵌套

  • Mybatis中连接查询和嵌套查询实例代码

    首先在mysql中确立表: #表一:地址国家表 CREATE TABLE address(aid INT AUTO_INCREMENT PRIMARY KEY,aname VARCHAR(20)); INSERT INTO address VALUES(NULL,"魏国"); INSERT INTO address VALUES(NULL,"蜀国"); INSERT INTO address VALUES(NULL,"吴国"); #表二:出场人物

  • 详解mybatis中的if-else的嵌套使用

    目录 案例一:if-else 案例二:if嵌套 MyBatis中if和choose的嵌套 案例一:if-else 在mybatis的使用过程中,难免会存在使用if-else的逻辑,但是实际是没有这种语法的,提供了choose标签来替代这种语法 <select id="selectUserByState" resultType="com.bz.model.entity.User"> SELECT * FROM user WHERE 1=1 <choo

  • 详解mybatis中association和collection的column传入多个参数问题

    项目中在使用association和collection实现一对一和一对多关系时需要对关系中结果集进行筛选,如果使用懒加载模式,即联合使用select标签时,主sql和关系映射里的sql是分开的,查询参数传递成为问题. mybatis文档: property description column 数据库的列名或者列标签别名.与传递给resultSet.getString(columnName)的参数名称相同.注意: 在处理组合键时,您可以使用column="{prop1=col1,prop2=c

  • mybatis利用association或collection传递多参数子查询

    有时候我们在查询数据库时,需要以查询结果为查询条件进行关联查询. 在mybatis 中通过 association 标签(一对一查询,collection 一对多 查询) 实现延迟加载子查询 <resultMap id="xxxMap" type="xxxx.bean.xxx" extends="zzzzMap"> <association property="destName" javaType="

  • Mybatis之association和collection用法

    目录 association和collection用法 1.单个关联查询association 2.多个关联查询 collection 3.鉴别器discriminator association和collection关联查询用法 一对多 collection 一对一 & 多对一 association和collection用法 1.单个关联查询association 1.1实体之间的关联表示 package com.worldly.config.entity; import java.io.S

  • 在Mybatis中association标签多层嵌套的问题

    目录 association标签多层嵌套问题 排查 从代码上看没有什么问题 正常代码如下 association集合嵌套 这个返回集合有什么用呢 association标签多层嵌套问题 mybatis里查询使用嵌套association标签时,发现内层的association查询的结果一直为null 排查 检查sql执行情况,发现有数据返回,排除 检查property的值是否和pojo中的对应,值一致,排除 检查column的值是否和数据库的相对应,相对应,排除 那么应该是mybatis没有把数

随机推荐