商品详情
详情数据的实体类
最外层
@Datapublic class SkuItemVO {/*** 1、sku基本信息【标题、副标题、价格】pms_sku_info* 2、sku图片信息【每个sku_id对应了多个图片】pms_sku_images* 3、spu下所有sku销售属性组合【不只是当前sku_id所指定的商品】* 4、spu商品介绍【】* 5、spu规格与包装【参数信息】*///1、sku基本信息(pms_sku_info)【默认图片、标题、副标题、价格】private SkuInfoEntity info;private boolean hasStock = true;// 是否有货//2、sku图片信息(pms_sku_images)private List<SkuImagesEntity> images;//3、当前sku所属spu下的所有销售属性组合(pms_sku_sale_attr_value)private List<SkuItemSaleAttrVO> saleAttr;//4、spu商品介绍(pms_spu_info_desc)【描述图片】private SpuInfoDescEntity desc;//5、spu规格参数信息(pms_attr)【以组为单位】private List<SpuItemAttrGroupVO> groupAttrs;}
销售属性组合
@Data@ToStringpublic class SkuItemSaleAttrVO {/*** 1.销售属性对应1个attrName* 2.销售属性对应n个attrValue* 3.n个sku包含当前销售属性(所以前端根据skuId交集区分销售属性的组合【笛卡尔积】)*/private Long attrId;private String attrName;private List<AttrValueWithSkuIdVO> attrValues;}@Datapublic class AttrValueWithSkuIdVO {private String attrValue;private String skuIds;}
规格参数
@Data@ToStringpublic class SpuItemAttrGroupVO {private String groupName;private List<Attr> attrs;}@Datapublic class Attr {private Long attrId;private String attrName;private String attrValue;private Integer searchType;private Integer valueType;private String icon;private String valueSelect;private Integer attrType;private Long enable;private Long catelogId;private Integer showDesc;}
Controller
@Controllerpublic class ItemController {@Autowiredprivate SkuItemService skuItemService;@GetMapping("/{skuId}.html")public String item(@PathVariable("skuId") String skuId, Model model) throws ExecutionException, InterruptedException {SkuItemVo skuItemVo = skuItemService.item(skuId);model.addAttribute("item", skuItemVo);return "item";}}
service查询VO返回(异步编排)
注意:
此处用到的重要技术就是异步编排的使用,开多个线程来查询不同数据的信息。并在主线程获取其返回结果。
@Servicepublic class SkuItemServiceImpl implements SkuItemService {@Autowiredprivate SkuInfoService skuInfoService;@Autowiredprivate SkuImagesService skuImagesService;@Autowiredprivate SpuInfoDescService spuInfoDescService;@Autowiredprivate AttrGroupService attrGroupService;@Autowiredprivate SkuSaleAttrValueService skuSaleAttrValueService;@Autowiredprivate ThreadPoolExecutor executor;@Overridepublic SkuItemVo item(String skuId) throws ExecutionException, InterruptedException {SkuItemVo skuItemVo = new SkuItemVo();CompletableFuture<SkuInfoEntity> skuInfoFuture = CompletableFuture.supplyAsync(() -> {// 1.获取sku基本信息(pms_sku_info)【默认图片、标题、副标题、价格】SkuInfoEntity skuInfoEntity = skuInfoService.getById(skuId);skuItemVo.setInfo(skuInfoEntity);return skuInfoEntity;}, executor);// 2.获取sku图片信息(pms_sku_images)List<SkuImagesEntity> imagesEntityList = skuImagesService.getImgBySkuId(skuId);skuItemVo.setImages(imagesEntityList);CompletableFuture<Void> AttrFuture = skuInfoFuture.thenAcceptAsync(res -> {// 3.获取当前sku所属spu下的所有销售属性组合(pms_sku_info、pms_sku_sale_attr_value)List<SkuItemSaleAttrVo> skuItemSaleAttrVoList = skuSaleAttrValueService.getSaleAttrsBySpuId(res.getSpuId());skuItemVo.setSaleAttr(skuItemSaleAttrVoList);}, executor);CompletableFuture<Void> spuDescFuture = skuInfoFuture.thenAcceptAsync(res -> {// 4.获取spu商品介绍(pms_spu_info_desc)【描述图片】SpuInfoDescEntity spuInfoDescEntity = spuInfoDescService.getById(res.getSpuId());skuItemVo.setDesc(spuInfoDescEntity);}, executor);CompletableFuture<Void> groupFuture = skuInfoFuture.thenAcceptAsync((res -> {// 5.获取spu规格参数信息(pms_product_attr_value、pms_attr_attrgroup_relation、pms_attr_group)List<SpuItemAttrGroupVo> groupAttrList = attrGroupService.getGroupAttrGroupWithAttrsBySpuId(res.getSpuId(), res.getCatalogId());skuItemVo.setGroupAttrs(groupAttrList);}), executor);CompletableFuture.allOf(skuInfoFuture, AttrFuture, spuDescFuture, groupFuture).get(); // 阻塞等待所有执行完成return skuItemVo;}}
获取spu销售属性组合(笛卡尔积)
查询所有属性的skuId交集,组成sku笛卡尔积
GROUP_CONCAT操作是将所有分组的sku_id连接起来,注意去重

获取当前sku所属spu下的所有销售属性组合(pms_sku_info、pms_sku_sale_attr_value)// 1.通过spuId查询所有sku(pms_sku_info)// 2.查询sku涉及到的所有销售属性(pms_sku_sale_attr_value)/*** 1.销售属性对应1个attrName* 2.销售属性对应n个attrValue* 3.n个sku包含当前销售属性(所以前端根据skuId交集区分销售属性的组合【笛卡尔积】)* sku_ids用,切割成List<String> skuIds*/<resultMap id="skuItemSaleAttrVo" type="com.atguigu.gulimall.product.vo.SkuItemSaleAttrVo"><result column="attr_id" property="attrId"></result><result column="attr_name" property="attrName"></result><collection property="attrValues" ofType="com.atguigu.gulimall.product.vo.AttrValueWithSkuIdVo"><result column="attr_value" property="attrValue"></result><result column="sku_ids" property="skuIds"></result></collection></resultMap><select id="getSaleAttrsBySpuId" resultMap="skuItemSaleAttrVo">SELECT pss.attr_id, pss.attr_name, pss.attr_value, GROUP_CONCAT(DISTINCT pss.sku_id) sku_idsFROM pms_sku_info psLEFT JOIN pms_sku_sale_attr_value pss ON pss.sku_id = ps.sku_idWHERE ps.spu_id = #{spuId}GROUP BY pss.attr_id, pss.attr_name, pss.attr_value;</select>
获取spu规格参数信息
<resultMap id="spuItemAttrGroupVo" type="com.atguigu.gulimall.product.vo.SpuItemAttrGroupVo"><result property="groupName" column="attr_group_name"></result><collection property="attrs" ofType="com.atguigu.gulimall.product.vo.Attr"><result property="attrId" column="attr_id"></result><result property="attrName" column="attr_name"></result><result property="attrValue" column="attr_value"></result></collection></resultMap><!-- 自定义返回结果集 --><select id="getGroupAttrGroupWithAttrsBySpuId" resultMap="spuItemAttrGroupVo">SELECT pav.spu_id, ag.attr_group_name, ag.attr_group_id, pa.attr_id, pa.attr_name, pav.attr_valueFROM pms_attr_group agLEFT JOIN pms_attr_attrgroup_relation paa ON paa.attr_group_id = ag.attr_group_idLEFT JOIN pms_attr pa ON pa.attr_id = paa.attr_idLEFT JOIN pms_product_attr_value pav ON pav.attr_id = pa.attr_idWHERE ag.catelog_id = #{catalogId}AND pav.spu_id = #{spuId};</select>
