链表式查询 返回数据结构
{
"id":1,
"name":"鱼肉茄子套餐",
"price":12.50, // 套餐价格
"profit":9.19, // 套餐利润= 套餐价格-(套餐食材价格总数)
"createDate":1645670200000,
"goodsVoList":[
{
"goodsName":"茄子",
"id":1,
"price":1.21 // 食材价格
},
{
"goodsName":"鱼肉",
"id":7,
"price":2.10}]
}
在遇到这样的数据时一般都是 分两次进入数据库查询。但是mybatis的collection可以帮助我们一次查询出来。
数据库表
goods: 食材表
goods_packages:套餐表
goods_packages_shop: 关联表将套餐与食材管理在一起
返回实体类
注:不是表的实体类是用于返回htlm的数据类故此没有@TableName("")注解
注2:如果出现报错 可将@EqualsAndHashCode(callSuper = false),@Accessors(chain = true)两个注解删除试试。不确定是否可以,我加这两个注解无错误,但是我朋友会报错。
package com.io.vo;
import io.swagger.annotations.ApiModelProperty;
import lombok.*;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.List;
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
public class GoodsPackagesVo implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty("套餐id")
private Integer id;
@ApiModelProperty("套餐名称")
private String name;
@ApiModelProperty("套餐价格")
private BigDecimal price;
@ApiModelProperty("套餐利润: 价格减 食材价格")
private BigDecimal profit;
@ApiModelProperty("创建时间")
private Timestamp createDate;
@ApiModelProperty("套餐食材")
private List<GoodsVo> goodsVoList;
}
package com.io.vo;
import io.swagger.annotations.ApiModelProperty;
import lombok.*;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.math.BigDecimal;
@Data
@ToString
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
public class GoodsVo implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty("套餐id")
private Integer id;
@ApiModelProperty("套餐id")
private String goodsName;
@ApiModelProperty("食材价格")
private BigDecimal price;
}
*主要代码
mybatis的XML(Dao)
// 查询餐厅套餐以及套餐下的食材 (Dao)
List<GoodsPackagesVo> getGoodsPackagesVo();
-- XML
-- column:返回的列名 property:(实体类属性名)赋值的属性名
-- association:也可以使用链表查询赋值但只能返回一个值,不可有多个。
-- collection:链表查询可查询多条数据。
-- select:xml中写好的<select的id> sql
-- 链表查询条件 这是传多条数据条件 column="{goodsPackagesId=id,totalPrice=price}" goodsPackagesId是子sql中的 条件#{goodsPackagesId} id是当前<resultMap>中的<result column="id">
-- 链表查询条件 单 column="id" id是当前<resultMap>中的<result column="id"> #{id}
<resultMap id="GoodsPackagesVoMap" type="com.io.vo.GoodsPackagesVo">
<result column="id" property="id" jdbcType="INTEGER"/>
<result column="name" property="name" jdbcType="VARCHAR"/>
<result column="price" property="price" jdbcType="DECIMAL"/>
<result column="create_date" property="createDate"/>
<association column="{goodsPackagesId=id,totalPrice=price}" property="profit" javaType="java.math.BigDecimal" select="sqlSumProfit"/>
<collection property="goodsVoList" column="id" select="getGoodsVoList">
<result property="id" column="id"/>
<result property="goodsName" column="goodsName"/>
<result property="price" column="price"/>
</collection>
</resultMap>
<select id="sqlSumProfit" resultType="java.math.BigDecimal">
-- 多条件查询 #{totalPrice},#{goodsPackagesId} 都是association的column传过来的参数
SELECT #{totalPrice} - SUM(g.price)
FROM goods_packages_shop AS gps
LEFT JOIN goods AS g ON gps.goods_id = g.id
WHERE gps.goods_packages_id = #{goodsPackagesId}
</select>
<select id="getGoodsVoList" resultType="com.io.vo.GoodsVo">
-- 查询子表goods数据。#{id}是单查询
SELECT
g.id,g.`name` AS goodsName,g.price
FROM goods_packages_shop AS gps
LEFT JOIN goods AS g ON gps.goods_id = g.id
WHERE gps.goods_packages_id = #{id}
</select>
<select id="getGoodsPackagesVo" resultMap="GoodsPackagesVoMap">
-- 主数据
SELECT id,`name`,price,create_date
FROM goods_packages AS gp
</select>