商品模型
在视频的一开始,视频说应该先设计领域模型。(我一般都是先设计数据库的,这里涨知识了)
在这里,库存用了另外一张表。
ItemModel.java
@Data
public class ItemModel {
private Integer id;
@NotBlank(message = "商品名称不能为空")
private String title;
@NotNull(message = "商品价格不能为空")
@Min(value = 0, message = "商品价格必须大于0")
private BigDecimal price;
@NotNull(message = "库存不能为空")
@Min(value = 0, message = "库存必须大于0")
private Integer stock;
@NotNull(message = "商品表述信息不能为空")
private String description;
//销量
private Integer sales;
@NotNull(message = "商品图片不能为空")
private String imgUrl;
}
由于需要重新利用mybatis的generator,所以要被自动覆盖设置为false。避免之前的改动没了(在这里,我之前看的视频时,自己写的mapper.xml最好用一个新的文件保存)
mybatis-generator.xml增加下列代码。同时最好注释之前生成的类的代码
<table tableName="item" domainObjectName="ItemDO"
enableCountByExample="false" enableUpdateByExample="false"
enableDeleteByExample="false" enableSelectByExample="false"
selectByExampleQueryId="false"></table>
<table tableName="item_stock" domainObjectName="ItemStockDO"
enableCountByExample="false" enableUpdateByExample="false"
enableDeleteByExample="false" enableSelectByExample="false"
selectByExampleQueryId="false"></table>
重新运行mybatis-generator。生成类【如果用idea可以直接利用maven插件,点击即可】
对所有的增加语句添加获取自增id
keyProperty="id" useGeneratedKeys="true"
给 ItemStockDOMapper 添加方法
ItemStockDO selectByItemId(Integer itemId);
ItemStockDOMapper.xml增加下列句子
<select id="selectByItemId" parameterType="java.lang.Integer" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from item_stock
where item_id = #{itemId,jdbcType=INTEGER}
</select>
创建 ItemService
public interface ItemService {
//创建商品
ItemModel createItem(ItemModel itemModel) throws BusinessException;
//商品列表浏览
List<ItemModel> listItems();
//商品详情 根据Id查找。
ItemModel getItemById(Integer id);
}
创建 ItemServiceImpl
@Service
public class ItemServiceImpl implements ItemService {
@Autowired
private ValidatorImpl validator;
@Autowired
private ItemDOMapper itemDOMapper;
@Autowired
private ItemStockDOMapper itemStockDOMapper;
@Transactional
@Override
public ItemModel createItem(ItemModel itemModel) throws BusinessException {
//检验入参
ValidationResult result = validator.validate(itemModel);
if (result.isHasErrors()) {
throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR, result.getErrMsg());
}
//转化itemModel -> dataObject
ItemDO itemDO = this.convertItemDOFromItemModel(itemModel);
//写入数据库
itemDOMapper.insertSelective(itemDO);
itemModel.setId(itemDO.getId());
ItemStockDO itemStockDO = this.covertItemStockDOFromItemModel(itemModel);
itemStockDOMapper.insertSelective(itemStockDO);
//返回创建完成的对象
return this.getItemById(itemModel.getId());
}
@Override
public List<ItemModel> listItems() {
return null;
}
@Override
public ItemModel getItemById(Integer id) {
ItemDO itemDO = itemDOMapper.selectByPrimaryKey(id);
if (itemDO == null)
return null;
//获取库存
ItemStockDO itemStockDO = itemStockDOMapper.selectByItemId(itemDO.getId());
ItemModel itemModel = convertModelFromDataObject(itemDO, itemStockDO);
return itemModel;
}
private ItemDO convertItemDOFromItemModel(ItemModel itemModel) {
if (itemModel == null)
return null;
ItemDO itemDO = new ItemDO();
BeanUtils.copyProperties(itemModel, itemDO);
//因为一个是double类型。 一个是bigDecimal类型。
//所以这里需要手动转换
itemDO.setPrice(itemModel.getPrice().doubleValue());
return itemDO;
}
private ItemStockDO covertItemStockDOFromItemModel(ItemModel itemModel) {
if (itemModel == null)
return null;
ItemStockDO itemStockDO = new ItemStockDO();
itemStockDO.setItemId(itemModel.getId());
itemStockDO.setStock(itemModel.getStock());
return itemStockDO;
}
private ItemModel convertModelFromDataObject(ItemDO itemDO, ItemStockDO itemStockDO) {
ItemModel itemModel = new ItemModel();
BeanUtils.copyProperties(itemDO, itemModel);
itemModel.setPrice(new BigDecimal(itemDO.getPrice()));
itemModel.setStock(itemStockDO.getStock());
return itemModel;
}
}
创建ItemVO
@Data
public class ItemVO {
private Integer id;
private String title;
private BigDecimal price;
//库存
private Integer stock;
private String description;
//销量
private Integer sales;
private String imgUrl;
}
创建 ItemController
@Controller("item")
@RequestMapping("/item")
@CrossOrigin(allowCredentials = "true", allowedHeaders = "*")
public class ItemController extends BaseController {
@Autowired
private ItemService itemService;
@RequestMapping(value = "/create", method = {RequestMethod.POST}, consumes = {CONTENT_TYPE_FORMED})
@ResponseBody
public CommonReturnType createItem(ItemModel item) throws BusinessException {
ItemModel itemModel = itemService.createItem(item);
ItemVO itemVO = convertFromModel(itemModel);
return CommonReturnType.create(itemVO);
}
@RequestMapping(value = "/get", method = {RequestMethod.GET})
@ResponseBody
public CommonReturnType getItem(@RequestParam(name="id") Integer id){
ItemModel itemModel = itemService.getItemById(id);
ItemVO itemVO = convertFromModel(itemModel);
return CommonReturnType.create(itemVO);
}
private ItemVO convertFromModel(ItemModel itemModel){
if(itemModel == null){
return null;
}
ItemVO itemVO = new ItemVO();
BeanUtils.copyProperties(itemModel, itemVO);
return itemVO;
}
页面绘制【来自于
https://www.cnblogs.com/victorbu/p/10573393.html
】
<html>
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
</head>
<body>
<div id="app">
<el-row>
<el-col :span="8" :offset="8">
<h3>创建商品</h3>
<el-form ref="form" :model="item" label-width="80px">
<el-form-item label="商品名">
<el-input v-model="item.title"></el-input>
</el-form-item>
<el-form-item label="商品描述">
<el-input v-model="item.description"></el-input>
</el-form-item>
<el-form-item label="价格">
<el-input v-model="item.price"></el-input>
</el-form-item>
<el-form-item label="图片">
<el-input v-model="item.imgUrl"></el-input>
</el-form-item>
<el-form-item label="库存">
<el-input v-model="item.stock"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">提交</el-button>
</el-form-item>
</el-form>
</el-col>
</el-row>
</div>
</body>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://cdn.bootcss.com/axios/0.18.0/axios.min.js"></script>
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<script>
var app = new Vue({
el: '#app',
data: {
item: {
title: '',
price: 0,
description: '',
stock: 1,
imgUrl: '',
}
},
methods: {
onSubmit(){
// https://www.cnblogs.com/yesyes/p/8432101.html
axios({
method: 'post',
url: 'http://localhost:8080/item/create',
data: this.item,
params: this.item,
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
withCredentials: true,
})
.then(resp=>{
if(resp.data.status == 'success'){
this.$message({
message: '创建成功',
type: 'success'
});
}else{
this.$message.error('创建失败,原因为:' + resp.data.data.errMsg);
}
})
.catch(err =>{
this.$message.error('创建失败,原因为:' + err.status + ', ' + err.statusText);
});
},
},
});
</script>
</html>
商品详情
ItemDOMapjie'接口增加新方法
List<ItemDO> listItem();
添加对应的xml代码(ItemDOMapper.xml)。
<select id="listItem" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from item
order by sales desc ;
</select>
ItemServiceImpl 编写对应方法
@Override
public List<ItemModel> listItems() {
List<ItemDO> itemDOS = itemDOMapper.listItem();
List<ItemModel> itemModels = new ArrayList<>();
for(int i = 0;i < itemDOS.size(); i++){
ItemStockDO itemStockDO = itemStockDOMapper.selectByItemId(itemDOS.get(i).getId());
itemModels.add(convertModelFromDataObject(itemDOS.get(i),itemStockDO));
}
return itemModels;
// java 8的Stream方法
// List<ItemModel> itemModelList = itemDOS.stream().map(itemDO -> {
// ItemStockDO itemStockDO = itemStockDOMapper.selectByItemId(itemDO.getId());
// ItemModel itemModel = convertModelFromDataObject(itemDO,itemStockDO);
// return itemModel;
// }).collect(Collectors.toList());
// return itemModelList;
}
ItemController编写对应代码
@RequestMapping(value = "/list", method = RequestMethod.GET)
@ResponseBody
public CommonReturnType listItem(){
List<ItemModel> itemModels = itemService.listItems();
List<ItemVO> itemVOs = itemModels.stream().map(itemModel -> {
ItemVO itemVO = convertFromModel(itemModel);
return itemVO;
}).collect(Collectors.toList());
return CommonReturnType.create(itemVOs);
}
页面代码。【由于参考的代码的页面没有写好,自己改了点东西。 不过图片没有显示出来。。。】
<html>
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
</head>
<body>
<div id="app">
<template>
<el-table :data="items" stripe style="width: 100%">
<el-table-column prop="title" label="商品名" width="180">
</el-table-column>
<el-table-column prop="description" label="商品描述" width="180">
</el-table-column>
<el-table-column prop="imgUrl" label="商品图片">
</el-table-column>
<el-table-column prop="price" label="商品价格">
</el-table-column>
<el-table-column prop="stock" label="商品库存">
</el-table-column>
<el-table-column prop="sales" label="商品销量">
</el-table-column>
</el-table>
</template>
</div>
</body>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://cdn.bootcss.com/axios/0.18.0/axios.min.js"></script>
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<script>
var app = new Vue({
el: '#app',
data: {
items: [],
},
methods: {
},
created: function() {
var vm = this
axios({
method: 'get',
url: 'http://localhost:8080/item/list',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
withCredentials: true,
})
.then(resp => {
vm.items = resp.data.data
})
.catch(err => {
this.$message.error('获取信息失败,原因为:' + err.status + ', ' + err.statusText);
});
}
});
</script>
</html>
总结
商品信息的模块就做完了。 感觉也差不多吧,只是简单的CRUD。不过有好多的转化函数需要些,比如dataObject转换成model型的。 可能是之前做的小设计没有出现过这么多东西吧,感觉总是忘记。