7_根据三级分类查询group_name_根据关键字,页数,每页行数_上下架查询spu对象显示spu_id, spu_titile_品牌,分类名

总结:

功能:根据三级分类查询group_name

查询tb_group表即可:根据cid查询name
tb_spec_group表:id name cid
http://api.leyou.com/api/item/spec/groups/76
返回:ResponseEntity

功能:根据关键字,分页,每页行数,上下架,查询结果,显示:spu_id, spu_titile, 商品分类,商品品牌

查询tb_spec_spu表,: 根据key, saleble, page, rows查询spu对象
tb_spu表: id, title, spu_titile, group_id, cid1, cid2, cid3, brandId, valid, create_time, last_updat_time
http://api.leyou.com/api/item/spu/page?key=&saleable=true&page=1&rows=5
返回:ResponseEntity<PageRessult> PageResult在List上增加了总条数,总页数,

注意点:
1.因为tb_spec_spu只有cid, brand_id字段,即对应的pojoSpu也只有Integer cid, Integer bid, 所以要包装Spu–SpuBo(添加了cname, 和bname字段)

根据:关键字,分页,每页行数,上下架查询得到List对象后:
2. 关键字查询: Example.Criteria添加模糊查询条件,riteria.andLike(“title”, “%” + key + “%”);
3. 上下架查询: Example.Criteria添加上下架字段查询,criteria.andEqualTo(“saleable”, saleable);
4. 页数,每页条数查询:PageHelper.startPage(page, rows);

根据Spu对象,显示
商品分类,商品品牌查询:
根据spu对象,得到spu对象的cid, 根据cid1, cid2, cid3查询tb_categry表,得到分类集合(三个级的分类集合),写入SpuBo类。
SelectByIdListMapper<Category, Long>

List names = this.categoryService.queryNamesByIds(Arrays.asList(spu.getCid1(), spu.getCid2(), spu.getCid3()));

spuBo.setCname(StringUtils.join(names, “/”));

根据spu对象,得到spu对象的bid, 根据bid查询tb_brand表,得到对应品牌名称,写入SpuBo对象

spu,_id, spu_titile显示
因为SpuBo继承了Spu,tb_spu表里有这些字段,所以也是有这些属性的。

在查询得到List对象后,要用forEach对每一个Spu,分别查询分类名称和品牌名称


表结构

前面实现了:查询全部分类,查询全部品牌
接触了三张表:tb_category,tb_brand,tb_brand_category
tb_category: id name parant_id, is_parent_id,sort
tb_brand: id name image
tb_brand_category: id_brand, id_category

易错:由于品牌和分类是多对多的关系,所以在tb_category, tb_brand 两张表中,只有自己的id,不是根据外键关联,关联是通过中间表关联。

五张表:

tb_spec_group: id cid name
在这里插入图片描述
tb_spec_params: id cid group_id name generic searching numeric segment
在这里插入图片描述
tb_spu: id cid1 cid2 cid3 title brand_id
在这里插入图片描述
tb_spu_detail : spu_id, description special_spec
在这里插入图片描述
tb_sku: id spu_id,indexes, own_spec
在这里插入图片描述

点击手机,查看手机的规格参数:
在这里插入图片描述
点击手机:
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
Request URL: http://api.leyou.com/api/item/spec/groups/76

  • 请求方式:get

  • 请求路径:/spec/groups/{cid} ,这里通过路径占位符传递商品分类的id

  • 请求参数:商品分类id

  • 返回结果:页面是直接把resp.data赋值给了groups:

那么我们返回的应该是规格组SpecGroup的集合

规格参数查询:根据group_id查询spec_params

后端代码

实体类

@Table(name = "tb_spec_group")
public class SpecGroup {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private Long cid;

    private String name;

    @Transient
    private List<SpecParam> params;

   // getter和setter省略
}
@Table(name = "tb_spec_param")
public class SpecParam {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private Long cid;
    private Long groupId;
    private String name;
    @Column(name = "`numeric`")
    private Boolean numeric;
    private String unit;
    private Boolean generic;
    private Boolean searching;
    private String segments;
    
    // getter和setter ...
}

mapper

public interface SpecGroupMapper extends Mapper<SpecGroup> {
}

controller

Request URL: http://api.leyou.com/api/item/spec/groups/76

  • 请求方式:get

  • 请求路径:/spec/groups/{cid} ,这里通过路径占位符传递商品分类的id

  • 请求参数:商品分类id

  • 返回结果:页面是直接把resp.data赋值给了groups:
    在这里插入图片描述
    那么我们返回的应该是规格组SpecGroup的集合

@RestController
@RequestMapping("spec")
public class SpecificationController {

    @Autowired
    private SpecificationService specificationService;

    /**
     * 根据分类id查询分组
     * @param cid
     * @return
     */
    @GetMapping("groups/{cid}")
    public ResponseEntity<List<SpecGroup>> queryGroupsByCid(@PathVariable("cid")Long cid){
        List<SpecGroup> groups = this.specificationService.queryGroupsByCid(cid);
        if (CollectionUtils.isEmpty(groups)){
            return ResponseEntity.notFound().build();
        }
        return ResponseEntity.ok(groups);
    }
}

service

@Service
public class SpecificationService {

    @Autowired
    private SpecGroupMapper groupMapper;

    /**
     * 根据分类id查询分组
     * @param cid
     * @return
     */
    public List<SpecGroup> queryGroupsByCid(Long cid) {
        SpecGroup specGroup = new SpecGroup();
        specGroup.setCid(cid);
        return this.groupMapper.select(specGroup);
    }
}

页面访问测试:

目前,我们数据库只为手机分类(76)提供了规格组:
在这里插入图片描述

我们访问:http://api.leyou.com/api/item/spec/groups/76
在这里插入图片描述

规格参数查询

查看页面控制台,发现请求已经发出:

在这里插入图片描述

报404,因为我们还没有实现后台逻辑,接下来就去实现。

后台实现

SpecificationController

分析:

  • 请求方式:GET
  • 请求路径:/spec/params
  • 请求参数:gid,分组id
  • 返回结果:该分组下的规格参数集合List<SpecParam>

代码:

/**
     * 根据条件查询规格参数
     * @param gid
     * @return
     */
@GetMapping("params")
public ResponseEntity<List<SpecParam>> queryParams(@RequestParam("gid")Long gid){
    List<SpecParam>  params = this.specificationService.queryParams(gid);
    if (CollectionUtils.isEmpty(params)){
        return ResponseEntity.notFound().build();
    }
    return ResponseEntity.ok(params);
}

SpecificationService

@Autowired
private SpecParamMapper paramMapper;

/**
     * 根据条件查询规格参数
     * @param gid
     * @return
     */
public List<SpecParam> queryParams(Long gid) {
    SpecParam param = new SpecParam();
    param.setGroupId(gid);
    return this.paramMapper.select(param);
}

SecParamMapper

public interface SpecParamMapper extends Mapper<SpecParam> {
}

在这里插入图片描述

商品查询

效果预览

在这里插入图片描述
可以看出整体是一个table,然后有新增按钮。是不是跟昨天写品牌管理很像?

在这里插入图片描述
因此接下来,我们编写接口即可。

后台提供分页查询SPU的功能

在leyou-item-interface工程中添加实体类:

SPU

@Table(name = "tb_spu")
public class Spu {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private Long brandId;
    private Long cid1;// 1级类目
    private Long cid2;// 2级类目
    private Long cid3;// 3级类目
    private String title;// 标题
    private String subTitle;// 子标题
    private Boolean saleable;// 是否上架
    private Boolean valid;// 是否有效,逻辑删除用
    private Date createTime;// 创建时间
    private Date lastUpdateTime;// 最后修改时间
	// 省略getter和setter
}

SPU详情

@Table(name="tb_spu_detail")
public class SpuDetail {
    @Id
    private Long spuId;// 对应的SPU的id
    private String description;// 商品描述
    private String specialSpec;// 商品特殊规格的名称及可选值模板
    private String genericSpec;// 商品的全局规格属性
    private String packingList;// 包装清单
    private String afterService;// 售后服务
    // 省略getter和setter
}

4.4.2.mapper

public interface SpuMapper extends Mapper<Spu> {
}

4.3.3.controller

先分析:

  • 请求方式:GET

  • 请求路径:/spu/page

  • 请求参数:

    • page:当前页
    • rows:每页大小
    • key:过滤条件
    • saleable:上架或下架

Request URL: http://api.leyou.com/api/item/spu/page?key=&saleable=true&page=1&rows=5

  • 返回结果:商品SPU的分页信息。

    • 要注意,页面展示的是商品分类和品牌名称,而数据库中保存的是id,怎么办?

      我们可以新建一个类,继承SPU,并且拓展cname和bname属性,写到leyou-item-interface

      public class SpuBo extends Spu {
      
          String cname;// 商品分类名称
          
          String bname;// 品牌名称
          
          // 略 。。
      }
      

编写controller代码:

我们把与商品相关的一切业务接口都放到一起,起名为GoodsController,业务层也是这样

@Controller
public class GoodsController {

    @Autowired
    private GoodsService goodsService;

    @GetMapping("spu/page")
    public ResponseEntity<PageResult<SpuBo>> querySpuBoByPage(
            @RequestParam(value = "key", required = false)String key,
            @RequestParam(value = "saleable", required = false)Boolean saleable,
            @RequestParam(value = "page", defaultValue = "1")Integer page,
            @RequestP@aram(value = "rows", defaultValue = "5")Integer rows
    ){
        PageResult<SpuBo> pageResult = this.goodsService.querySpuBoByPage(key, saleable, page, rows);
        if(CollectionUtils.isEmpty(pageResult.getItems())){
            return ResponseEntity.notFound().build();
        }
        return ResponseEntity.ok(pageResult);
    }

}

4.4.4.service

所有商品相关的业务(包括SPU和SKU)放到一个业务下:GoodsService。

@Service
public class GoodsService {

    @Autowired
    private SpuMapper spuMapper;

    @Autowired
    private CategoryService categoryService;

    @Autowired
    private BrandMapper brandMapper;

    public PageResult<SpuBo> querySpuBoByPage(String key, Boolean saleable, Integer page, Integer rows) {

        Example example = new Example(Spu.class);
        Example.Criteria criteria = example.createCriteria();
        // 搜索条件
        if (StringUtils.isNotBlank(key)) {
            criteria.andLike("title", "%" + key + "%");
        }
        if (saleable != null) {
            criteria.andEqualTo("saleable", saleable);
        }

        // 分页条件
        PageHelper.startPage(page, rows);

        // 执行查询
        List<Spu> spus = this.spuMapper.selectByExample(example);
        PageInfo<Spu> pageInfo = new PageInfo<>(spus);

        List<SpuBo> spuBos = new ArrayList<>();
        spus.forEach(spu->{
            SpuBo spuBo = new SpuBo();
            // copy共同属性的值到新的对象
            BeanUtils.copyProperties(spu, spuBo);
            // 查询分类名称
            List<String> names = this.categoryService.queryNamesByIds(Arrays.asList(spu.getCid1(), spu.getCid2(), spu.getCid3()));
            spuBo.setCname(StringUtils.join(names, "/"));

            // 查询品牌的名称
            spuBo.setBname(this.brandMapper.selectByPrimaryKey(spu.getBrandId()).getName());

            spuBos.add(spuBo);
        });

        return new PageResult<>(pageInfo.getTotal(), spuBos);

    }
}

4.4.5.Category中拓展查询名称的功能

页面需要商品的分类名称需要在这里查询,因此要额外提供查询分类名称的功能,

在CategoryService中添加功能:

public List<String> queryNamesByIds(List<Long> ids) {
    List<Category> list = this.categoryMapper.selectByIdList(ids);
    List<String> names = new ArrayList<>();
    for (Category category : list) {
        names.add(category.getName());
    }
    return names;
    // return list.stream().map(category -> category.getName()).collect(Collectors.toList());
}

mapper的selectByIdList方法是来自于通用mapper。不过需要我们在mapper上继承一个通用mapper接口:

public interface CategoryMapper extends Mapper<Category>, SelectByIdListMapper<Category, Long> { 

}

4.5.测试

刷新页面,查看效果:

http://manage.leyou.com/#/item/list
http://api.leyou.com/api/item/spu/page?key=&saleable=true&page=1&rows=5
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值