实体类
在learn-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
}
mapper
public interface SpuMapper extends Mapper<Spu> {
}
controller
先分析:
-
请求方式:GET
-
请求路径:/spu/page
-
请求参数:
-
page:当前页
-
rows:每页大小
-
key:过滤条件
-
saleable:上架或下架
-
-
返回结果:商品SPU的分页信息。
-
要注意,页面展示的是商品分类和品牌名称,而数据库中保存的是id,怎么办?
我们可以新建一个类,继承SPU,并且拓展cname和bname属性,写到
learn-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,
@RequestParam(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);
}
}
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);
}
}
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> {
}
测试
刷新页面,查看效果:
基本与预览的效果一致,OK!