昨天的那个实战案例可能写的不是特别具体,其中有很多技术点需要深究的,这个就是实际的开发的数据结构和场景,估计在复杂也是跟这个数据的嵌套的情景是差不多的。
值得提的是实际接口在开发中有DTO就是数据传输对象,实体类可能有8个成员变量,实际的传值过程中只需要传值6个成员变量的,或者可能有额外的成员变量是当前实体类对象中没有的,这个时候怎么样很好的完成传值的呢?,那么就有两种思路:(1)一种是针对这个情况新建一个具体的dto,接口开发中涉及到这个类型的传输对象就用这个,
(2)还有就是新建一个基础的BaseRequestDto,BaseResponseDto,后面具体接口有新增的成员变量就直接继承这个类就行,对象传输对象实际就是一个类;
比如昨天的代码中的ProductVO和ProductInfoVO,ProductInfo就是按照第一种思路来操作的,其中:
@Data
public class ProductVO {
@JsonProperty("name")
private String categoryName;
@JsonProperty("type")
private Integer categoryType;
@JsonProperty("foods")
private List productInfoVOList;
}
@Data
public class ProductInfoVO {
@JsonProperty("id")
private String productId;
@JsonProperty("name")
private String productName;
@JsonProperty("price")
private BigDecimal productPrice;
@JsonProperty("description")
private String ProductDescription;
@JsonProperty("icon")
private String productIcon;
}
@Entity
@DynamicUpdate
@Data
public class ProductInfo {
/**
* 商品id
*/
@Id
private String productId;
/**
*商品名称
*/
private String productName;
/**
*单价
*/
private BigDecimal productPrice;
/**
*库存
*/
private Integer productStock;
/**
*描述
*/
private String productDescription;
/**
*小图
*/
private String productIcon;
/**
* 商品状态,0正常1下架
*/
private Integer productStatus;
/**
*类目编号
*/
private Integer categoryType;
/**
*创建时间
*/
private Date createTime;
/**
*修改时间
*/
private Date updateTime;
public ProductInfo() {
}
/**
* Title:
* Description:
* @param productId
* @param productName
* @param productPrice
* @param productStock
* @param productDecription
* @param productIcon
* @param productStatus
* @param categoryType
* @param createTime
* @param updateTime
*/
public ProductInfo(String productId, String productName, BigDecimal productPrice, int productStock,
String productDescription, String productIcon, int productStatus, int categoryType, Date createTime,
Date updateTime) {
super();
this.productId = productId;
this.productName = productName;
this.productPrice = productPrice;
this.productStock = productStock;
this.productDescription = productDescription;
this.productIcon = productIcon;
this.productStatus = productStatus;
this.categoryType = categoryType;
this.createTime = createTime;
this.updateTime = updateTime;
}
}
ProductInfoVO只包含部分的ProductInfo的属性, ProductVO包含List
返回值的类型来设置的:(接口文档)
###商品列表
```
GET /sell/buyer/product/list
```
参数
```
无
```
返回
```
{
"code": 0,
"msg": "成功",
"data": [
{
"name": "热榜",
"type": 1,
"foods": [
{
"id": "123456",
"name": "皮蛋粥",
"price": 1.2,
"description": "好吃的皮蛋粥",
"icon": "http://xxx.com",
}
]
},
{
"name": "好吃的",
"type": 2,
"foods": [
{
"id": "123457",
"name": "慕斯蛋糕",
"price": 10.9,
"description": "美味爽口",
"icon": "http://xxx.com",
}
]
}
]
}
最后是结果传输对象ResultVO:
@Data
public class ResultVO {
/**错误码.*/
private Integer code;
/**提示信息 .*/
private String msg;
/**返回值 .*/
private T data;
}
查询类目列表的控制器BuyerProductController
@RestController
@RequestMapping("/buyer/product")
public class BuyerProductController {
@Autowired
private ProductInfoService productService;
@Autowired
private CategoryService categoryService;
@GetMapping("/list")
public ResultVO list(){
//1.查询所有上架商品
List productInfoUpList = productService.findUpAll();
//2.查询类目--一次性查出来 此处使用到map 函数的作用是将流中的一个值转换成一个新的值
//Java 8 Lambda 表达式及 Stream 在集合中的用法
List categoryTypeList = productInfoUpList.stream().map(e -> e.getCategoryType()).collect(Collectors.toList());
List productCategoryList = categoryService.findByCategoryTypeIn(categoryTypeList);
//3.数据的拼装
List productVOList=new ArrayList();
for (ProductCategory productCategory : productCategoryList) {
ProductVO productVO=new ProductVO();
productVO.setCategoryType(productCategory.getCategoryType());
productVO.setCategoryName(productCategory.getCategoryName());
List productInfoVOList= new ArrayList();
for (ProductInfo productInfo : productInfoUpList) {
if(productInfo.getCategoryType()==(productCategory.getCategoryType())){
ProductInfoVO productInfoVO=new ProductInfoVO();
BeanUtils.copyProperties(productInfo,productInfoVO);
productInfoVO.setProductPrice(productInfo.getProductPrice());
productInfoVOList.add(productInfoVO);
}
}
productVO.setProductInfoVOList(productInfoVOList);
productVOList.add(productVO);
}
ResultVO resultVo =new ResultVO();
resultVo.setData(productVOList);
resultVo.setCode(0);
resultVo.setMsg("成功");
return resultVo;
}
}
综上几篇文章的汇总和说明,restful风格+注解开发就是一种高效方便的开发方式,涉及到的很多注解都非常值得深究。
比如涉及到传值对象的部分字段的非空校验,就可以使用@NotNull @NotEmpty @NotBlank,三者的区别就是:
@NotNull作用在成员变量上,不能为null,但是可以为empty;
@NotEmpty作用在成员变量上,不能为null,长度必须大于0;
@NotBlank作用在String类型的成员变量上,不能为空,而且调用trim()后长度必须大于0,值得注意的是,使用了
@NotBlank注解是必须在controller中传入传输对象时结合@valid注解,不然会报错。
未完待续...