如何用mybatis查询嵌套实体类(实体类中有另一个实体类)的数据

本文介绍了如何使用MyBatis框架中的resultMap来查询数据库时处理包含嵌套实体类(如List<MyList>)的数据,展示了resultMap的配置方法,以及如何通过SQL查询和关联映射获取所需信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

先看结果:

这是我查询出来的结果(这个放最前面是方便你看我的东西和你想知道的东西是不是一个东西)

[
    {
        "itemId": 1,
        "title": "动漫里最完美的父亲是谁",
        "titlePic": "",
        "avatarUrl": null,
        "nickName": null,
        "attendNum": 0,
        "myLists": [
            {
                "listId": null,
                "itemId": null,
                "name": "野原广志",
                "listPic": "",
                "commit": "小新啊爸爸也是第一次做爸爸啊,456",
                "averScore": 9.5,
                "source": "蜡笔小新",
                "attendNum": 0,
                "avatarUrl": null,
                "nickName": null,
                "title": null
            },
            {
                "listId": null,
                "itemId": null,
                "name": "波风水门",
                "listPic": "",
                "commit": "比主角还高的人气角色。",
                "averScore": 10.0,
                "source": "火影忍者",
                "attendNum": 0,
                "avatarUrl": null,
                "nickName": null,
                "title": null
            }
        ],
        "openid": null
    }
]

再看我的嵌套的实体类(实体类中有另一个实体类)

@Data
public class ItemVo {
    private Integer itemId;
    private String title;
    private String titlePic;
    private String avatarUrl;
    private String nickName;
    private Integer attendNum;
    //这是另一个实体类
    private List<MyList> myLists;
    private String openid;
}
@Data
public class MyList {
    private Integer listId;
    private Integer itemId;
    private String name;
    private String listPic;
    private String commit;
    private Double averScore;
    private String source;
    private Integer attendNum;
    private String avatarUrl;
    private String nickName;
    private  String title;
}

现在来看我是如何用mybatis查询实体类中有另一个实体类的数据

这里最重要的是这个resultMap,这个决定你能不能把数据库取出来的值放进第二层的实体类中。

可以看到我需要取的值我都用了在这里映射了。没映射的,从最上面的结果也可以看到。他的值全是null,图片相关的值是空的是我手动删的,我不想让你看。需要注意的是这里的 <id这一行要放最前面,不然会报错。

    <resultMap id="itemVoMap" type="com.lian.pet.domain.vo.ItemVo">
        <id property="itemId" column="ItemId"/>
        <result property="title" column="title"/>
        <result property="titlePic" column="titlePic"/>
        <result property="avatarUrl" column="avatarUrl"/>
        <result property="nickName" column="nickName"/>
        <result property="attendNum" column="attendNum"/>
        <result property="openid" column="openid"/>
        <collection property="myLists" ofType="com.lian.pet.domain.entity.MyList">
            <result property="name" column="listName"/>
            <result property="listPic" column="listPic"/>
            <result property="commit" column="listCommit" jdbcType="VARCHAR"/>
            <result property="averScore" column="listAverScore"/>
            <result property="source" column="listSource"/>
            <result property="attendNum" column="listAttendNum"/>
        </collection>
    </resultMap>
    

我的代码解决嵌套用的是collection是因为的是嵌套实体类用的是List<MyList>。

重要:

当数据库中查询结果的列直接对应了实体类的构造函数参数时,可以使用<constructor>元素。
如下所示
public class User {
    private int id;
    private String username;
    private String password;

    public User(int id, String username, String password) {
        this.id = id;
        this.username = username;
        this.password = password;
    }
}

这他的resultMap

<resultMap id="userResultMap" type="User">
    <id property="id" column="user_id"/>
    <constructor>
        <idArg column="user_id" javaType="int"/>
        <arg column="username" javaType="String"/>
        <arg column="password" javaType="String"/>
    </constructor>
</resultMap>
当你的实体类中包含另一个实体类的引用时,可以使用<association>来映射这种关联关系。

如下所示

public class Order {
    private int id;
    private User user; // 这是关联的User对象

    // Getters and setters
}

public class User {
    private int id;
    private String username;
    private String password;

    // Getters and setters
}

这他的resultMap

<resultMap id="orderResultMap" type="Order">
    <id property="id" column="order_id"/>
    <association property="user" javaType="User">
        <id property="id" column="user_id"/>
        <result property="username" column="username"/>
        <result property="password" column="password"/>
    </association>
</resultMap>
<collection>:当你的实体类中包含一个集合类型的属性时

如下所示

public class Order {
    private int id;
    private List<OrderItem> orderItems; // 这是包含多个OrderItem对象的集合

    // Getters and setters
}

public class OrderItem {
    private int id;
    private String name;
    private int quantity;

    // Getters and setters
}

这他的resultMap

<resultMap id="orderResultMap" type="Order">
    <id property="id" column="order_id"/>
    <collection property="orderItems" ofType="OrderItem">
        <id property="id" column="item_id"/>
        <result property="name" column="item_name"/>
        <result property="quantity" column="item_quantity"/>
    </collection>
</resultMap>
当你需要根据查询结果的某些值来确定映射到哪个子类型时,可以使用<discriminator>

如下所示

public class Vehicle {
    private int id;
    private String manufacturer;
    private String model;
    private int year;
    private int vehicleType;
    // Getters and setters
}

public class Car extends Vehicle {
    private int numberOfDoors;
    private String bodyStyle;

    // Getters and setters
}


public class Truck extends Vehicle {
    private double payloadCapacity;
    private String bedType;

    // Getters and setters
}

这他的resultMap

<resultMap id="vehicleResultMap" type="Vehicle">
    <id property="id" column="vehicle_id"/>
    <result property="manufacturer" column="manufacturer"/>
    <result property="model" column="model"/>
    <result property="year" column="year"/>
    <discriminator javaType="int" column="vehicle_type">
        <case value="1" resultMap="carResultMap"/>
        <case value="2" resultMap="truckResultMap"/>
    </discriminator>
</resultMap>

<resultMap id="carResultMap" type="Car">
    <result property="numberOfDoors" column="number_of_doors"/>
    <result property="bodyStyle" column="body_style"/>
</resultMap>

<resultMap id="truckResultMap" type="Truck">
    <result property="payloadCapacity" column="payload_capacity"/>
    <result property="bedType" column="bed_type"/>
</resultMap>

到这里就结束了。下面的都是无关紧要的东西了。

这里是我的查询语句,这个语句还蛮复杂的,但是和查询实体类中有另一个实体类的数据无关我就不赘述了。

<select id="temp" resultMap="itemVoMap">
        SELECT
            i.item_id AS ItemId,
            i.title,
            i.attend_num AS attendNum,
            i.title_pic AS titlePic,
            i.attend_num AS attendNum,
            l.list_id AS listId,
            l.name AS listName,
            l.list_pic AS listPic,
            l.attend_num AS listAttendNum,
            l.source AS listSource,
            c.commit AS listCommit,
            avgc.averScore AS listAverScore
        FROM
            item AS i
                LEFT JOIN list AS l ON i.item_id = l.item_id
                LEFT JOIN (
                SELECT
                    list_id,
                    GROUP_CONCAT(commit) AS commit
                FROM
                    list_commit
                GROUP BY
                    list_id
            ) AS c ON l.list_id = c.list_id
                LEFT JOIN (
                SELECT
                    list_id,
                    AVG(score) AS averScore
                FROM
                    list_commit
                GROUP BY
                    list_id
            ) AS avgc ON l.list_id = avgc.list_id
        ORDER BY
            i.item_id, l.list_id
            LIMIT 0, 10;

    </select>

下面是我的用到的表
item表

list表

list_commit表

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值