前言
上一章节,我们通过在html页面上架商品,但是查看上架的商品只能从数据库中,如何通过浏览器查看上架过的商品呢?这里我们需要了解一个html向后台发起请求的技术ajax,由于本系列着重点在Java开始上,前端的知识只会稍微介绍下。在原生的ajax技术,有一个封装好的前端js框架axios,所以接下来我们就用这个技术来遍历我们的商品。
商品列表
请求接口 good/getList
@GetMapping("getList")
public List<Good> getList() {
return goodService.getList();
}
dao层
<select id="getList" resultType="com.xiaoma.mall.entity.Good">
select id,name,remark,image,price from good
</select>
前端页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>小马哥商城</title>
</head>
<body>
<div id="app">
<h3>商品上架</h3>
<form action="good/shelves" method="post" enctype="multipart/form-data">
<div>商品名称<input name="name"></div>
<div>商品描述<input name="remark"></div>
<div>商品价格<input name="price"></div>
<div>商品图片<input name="file" type="file"></div>
<div><button type="submit">上架</button></div>
</form>
<div style="display:flex;flex-wrap: wrap;">
<div v-for="item in list" style="border:solid;margin:2px;padding:5px">
<p>商品名称:{{item.name}}</p>
<p>商品描述:{{item.remark}}</p>
<p>商品价格:{{item.price}}</p>
<image v-if="item.image" :src="'good/getGoodImg/'+item.image" style="width:50px;height:50px"/>
</div>
</div>
</div>
</body>
<script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.1/vue.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.0/axios.min.js"></script>
<script >
new Vue({
el:'#app',
data(){
return{
list:[]
}
},
created(){
axios
.get('good/getList')
.then(response => {
this.list = response.data
})
}
})
</script>
</html>
我们只要关注 axios .get('good/getList') .then(response =>this.list = response.data) ,先后台发起请求,获取接口返回的数据。
遍历数据
<div style="display:flex;flex-wrap: wrap;">
<div v-for="item in list" style="border:solid;margin:2px;padding:5px">
<p>商品名称:{{item.name}}</p>
<p>商品描述:{{item.remark}}</p>
<p>商品价格:{{item.price}}</p>
<image v-if="item.image" :src="'good/getGoodImg/'+item.image" style="width:50px;height:50px"/>
</div>
</div>
值得注意的是 image标签的 src值,在前面我们编写了一个获取图片的接口,那么在image标签上我们就可以直接用上了。
库存
商品列表中还查了一个数量的字段,前面我们表设计的时候 good表 warehouse表是通过goodId关联的,所以我们改动下我们的商品列表SQL的语句
SELECT
g.id,
g.NAME,
g.remark,
g.image,
g.price,
w.amount
FROM
good g
LEFT JOIN warehouse w on g.id = w.good_id
表名后面字母是表的别名,别名可以随便起的,字段的用表名.字段
warehouse表设计的时候少了amount字段,我们要补上
mybatis返回的对象跟我们good字段不一致,对了一个amount字段,这种情况我们可以在good类中增加一个amount字段,但是这样会破坏good类跟表结构不一致的情况,这里我们就引入一个新的知识点JSONObject。在pom.xml增加依赖
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.75</version>
</dependency>
将之前的接口改造下,返回类型变成JSONObject
@GetMapping("getList")
public List<JSONObject> getList() {
return goodService.getList();
}
GoodService
List<JSONObject> getList();
GoodServiceImpl
@Override
public List<JSONObject> getList() {
return goodDao.getList();
}
GoodDao
List<JSONObject> getList();
goodMapper
<select id="getList" resultType="com.alibaba.fastjson.JSONObject">
SELECT
g.id,
g.name,
g.remark,
g.image,
g.price,
w.amount
FROM
good g
LEFT JOIN warehouse w on g.id = w.good_id
</select>
index.html 增加数量显示
<p>商品价格:{{item.price}}</p>
<p>商品数量:{{item.amount||0}}</p>
库存更新
商品的库存要随时更新的,那么我们要实现一个库存更新接口。
前端页面我们先设计2个按钮,一个是增加,一个是减少。
html部分
<p>商品数量:{{item.amount||0}}
<button @click="updateWarehouse(item,0)">+</button>
<button @click="updateWarehouse(item,1)">-</button>
</p>
js部分
created(){
axios
.get('good/getList')
.then(response => {
this.list = response.data
})
},
methods:{
updateWarehouse(item,type){
axios
.post('warehouse/updateWarehouse',{
goodId:item.id,
type:type,
oldAmount:item.amount||0
}
)
.then(response => {
axios
.get('good/getList')
.then(response => {
this.list = response.data
})
})
}
}
首先我们先思考,进行数据更新的时候需要字段是什么,第一对商品存款更新一定要goodId,然后就是根据实际需要一个类型字段,还有一个是就得库存字段。
那么传到后台的字段为goodId, type,oldAmount。
/**
* 仓库接口
*
*/
@RestController
@RequestMapping("warehouse")
public class WarehouseController {
@Autowired
private WarehouseService warehouseService;
/**
* 更新商品库存 @RequestBody 注解表示接受一个json数据
*
* @param requestJson
* goodId 商品id
* type 0:存在增加 1:库存减少
* oldAmount 旧库存
* @return
*/
@PostMapping("updateWarehouse")
public String updateWarehouse(@RequestBody JSONObject requestJson){
return warehouseService.updateWarehouse(requestJson);
}
}
根据前端传进来的字段,从json中一一获取
@Service
public class WarehouseServiceImpl implements WarehouseService {
@Autowired
private WarehouseDao warehouseDao;
@Transactional
@Override
public String updateWarehouse(JSONObject requestJson) {
//从json数据获取字段值
int goodId = requestJson.getIntValue("goodId");
int type = requestJson.getIntValue("type");
int oldAmount = requestJson.getIntValue("oldAmount");
//先判断有无库存数据
Warehouse warehouse = warehouseDao.getWarehouseByGoodId(goodId);
if (warehouse == null) {
//无库存数据插入一条
warehouse = new Warehouse();
warehouse.setGoodId(goodId);
warehouse.setStatus(0);
warehouse.setAmount(0);
warehouse.setCreateTime(new Date());
warehouse.setCreateUser(1);
warehouseDao.addWarehouse(warehouse);
}
int amount;
if (type == 0) {//库存增加
amount = oldAmount + 1;
} else {//库存减少
amount = oldAmount - 1;
}
warehouseDao.updateWarehouse(goodId, amount, oldAmount);
return "ok";
}
}
sql语句为
<insert id="addWarehouse">
insert into warehouse(good_id,amount,status,create_time,create_user)
values(#{goodId},#{amount},#{status},#{createTime},#{createUser})
</insert>
<update id="updateWarehouse">
UPDATE warehouse
SET amount = #{amount}
WHERE
good_id = #{goodId}
AND amount = #{oldAmount}
</update>
<select id="getWarehouseByGoodId" resultType="com.xiaoma.mall.entity.Warehouse">
select
id,
good_id goodId,
amount
from warehouse
where good_id = #{goodId}
</select>
编写完后,重新启动项目,刷新index页面。点击+ - 按钮就能对商品的库存进行更新了。
小结
sql
- 表与表之间的关联可以通过left jon ,on为表之间的关联字段
- 表的别名 ,表名 空格 别名
- 字段别名, 字段 空格 别名
ajax -- axios
axios默认的请求头为application/json,当我们介绍post数据的时候,要通@RequestBody 注解将数据转换为java中的json对象。