说明
1.商品更新
不用发送请求回显
商品目录数据回显
商品更新后端实现
2.商品删除
mp/sql
3.商品下架/上架
restful风格接收参数(参数写在地址栏上)
4.富文本编辑器
5.重构商品新增(2张表)
动态获取入库的主键id(mp/sql) 事务控制
6.重构商品更新:restful风格接收参数,注意返回值有数据。
7.重构商品删除
1 商品分类名称回显实现(商品更新)
1.1 前端页面分析
回显说明:这里的回显不是在查询一次数据库而是把之前查询好的商品数据更改下回显到此页面,好处是:减少一次查询降低数据库访问压力。
1).
对应的页面:
2).
对应的页面:
1.2 实现更新页面目录数据回显
1.2.1 需求分析
说明:需要将 商品类目 3 改为具体的名称. 如何实现?
实现步骤:
- 通过选择器动态的获取商品分类ID 3
- 发起Ajax请求,根据3获取商品分类的名称. 电子书.
- 在指定的位置完成赋值操作.`
1.2.2 页面js
在之前查询模块回显叶子类目后端已经写过了,这个地方查询的也是叶子类目。所以只需要写前端即可。
//1.通过data数据返回商品分类id
var cid = data.cid;
//alert("我是商品分类目录id:"+cid);
//2.发起ajax请求,注意请求参数问题 必须与方法接收一致
$.get("/item/cat/queryItemName",{"itemCatId":cid},function(data){
//alert("动态获取数据:"+data);
//3.将数据回显到指定位置.
//$("#itemeEditForm input[name='cid']").siblings("span").text(data);
$("#itemeEditForm input[name='cid']").prev().text(data);
});
1.2.3 页面效果展现
1.3 商品修改后台实现
1.3.1 需求分析
1.url分析
2.参数根系分析
3.返回值结果确定:系统返回值。
1.3.2 编辑ItemController
注意:pojo,系统级别vo,mapper在前面写过了。
/**
* 业务说明: 商品修改操作
* url: /item/update
* 参数: 整个form表单
* 返回值: SysResult对象
*/
@RequestMapping("/update")
public SysResult updateItem(Item item){
itemService.updateItem(item);
return SysResult.success();
}
1.3.3 编辑ItemService
@Override
public void updateItem(Item item) {
itemMapper.updateById(item);
}
访问测试:
1.4 商品删除
1.4.1 需求分析
1.url地址的说明
2.请求参数
3.返回值分析:系统vo
$.messager.confirm('确认','确定删除ID为 '+ids+' 的商品吗?',function(r){
if (r){
var params = {"ids":ids};
$.post("/item/delete",params, function(data){
if(data.status == 200){
$.messager.alert('提示','删除商品成功!',undefined,function(){
$("#itemList").datagrid("reload");
});
}else{
$.messager.alert("提示",data.msg);
}
});
}
});
1.4.2 编辑ItemController
/**
* 商品删除
* url: /item/delete
* 参数: {"ids":"100,101,102"} ids数据类型是字符串!!!
* 返回值: 系统返回值变量
*/
@RequestMapping("/delete")
public SysResult deleteItems(Long... ids){// 可变参数/数组
itemService.deleteItems(ids);
return SysResult.success();
}
1.4.3 编辑ItemService
@Override
public void deleteItems(Long[] ids) {
//1.mp的方式实现删除
/*List<Long> longList = Arrays.asList(ids);//数组转化为集合
itemMapper.deleteBatchIds(longList);*/
//2.手动完成批量删除的操作.... 5分钟
itemMapper.deleteItems(ids);
}
1.4.4 编辑ItemMapper(手动)
public interface ItemMapper extends BaseMapper<Item>{
void deleteItems(Long[] ids);
}
1.4.5 编辑ItemMapper.xml文件(手动)
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.jt.mapper.ItemMapper">
<!--删除Item数据信息
单值: 数组 collection="array"
单值: list集合 collection="list"
多值: 利用Param注解封装 collection="key".
-->
<delete id="deleteItems">
delete from tb_item where id in (
<foreach collection="array" item="id" separator=",">
#{id}
</foreach>
)
</delete>
</mapper>
1.4.6 访问测试
1.5 商品上架/下架操作
1.5.1 业务说明
说明: 当用户点击上架/下架按钮时,需要修改item数据表中的status信息同时修改时间。
1.5.2 上架/下架URL地址说明
1). 页面url分析
2). 参数分析
3). 返回值结果分析
1.5.3 修改页面url地址
分析:当前上架,下架的url类似,后端代码几乎相同.正常情况下需要写2个控制层方法接收参数,能否通用的写法只写一个方法就能实现发送不同的请求呢?
解决:修改前端的url地址,改为可以用restful风格就可以用一个通用方法来接受。(前提是可以修改前端,如果给了接口文档的url地址,那还是写2个吧。)
1).修改前。
2).修改后。
1.5.4 编辑ItemController
/**
* 需求: 利用一个方法实现商品上架/下架操作 restFul风格实现
* url1:/item/updateStatus/2 status=2
* url2:/item/updateStatus/1 status=1
* 参数: ids: 1474391971,1474391970,1474391969
* 返回值: vo对象
*/
@RequestMapping("/updateStatus/{status}")
public SysResult updateStatus(@PathVariable Integer status, Long... ids){
itemService.updateStatus(status,ids);
return SysResult.success();
}
1.5.5 编辑ItemService
/**
* sql: update tb_item set status = #{status},updated={date}
* where id in (id1,id2,id3)
* MP机制实现
* @param status
* @param ids
*/
@Override
public void updateStatus(Integer status, Long[] ids) {
Item item = new Item(); //封装修改的值
item.setStatus(status);
UpdateWrapper<Item> updateWrapper = new UpdateWrapper<>();
updateWrapper.in("id", Arrays.asList(ids));
itemMapper.update(item,updateWrapper);
}
访问测试:
2.商品详情实现
2.1 富文本编辑器说明
2.1.1 介绍
KindEditor是一套开源的HTML可视化编辑器,主要用于让用户在网站上获得所见即所得编辑效果,兼容IE、Firefox、Chrome、Safari、Opera等主流浏览器。
所见即所得:就是在文本编辑器中编译一些标签,打开之后就可以动态的渲染出效果。
2.1.2 入门案例
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link href="/js/kindeditor-4.1.10/themes/default/default.css" type="text/css" rel="stylesheet">
<script type="text/javascript" charset="utf-8" src="/js/kindeditor-4.1.10/kindeditor-all-min.js"></script>
<script type="text/javascript" charset="utf-8" src="/js/kindeditor-4.1.10/lang/zh_CN.js"></script>
<script type="text/javascript" charset="utf-8" src="/js/jquery-easyui-1.4.1/jquery.min.js"></script>
<script type="text/javascript">
$(function(){
KindEditor.ready(function(){
//在指定的位置创建富文本编辑器
KindEditor.create("#editor")
})
})
</script>
</head>
<body>
<h1>富文本编辑器</h1>
<textarea style="width:700px;height:350px" id="editor"></textarea>
</body>
</html>
访问测试:
2.1.3 表设计
解释:一般查询商品后,点击其中的某一个商品才会展现出商品详情信息,为什么不一次性查询出来完,而分为2次查询呢?
因为:商品详情一般在数据库中存的都是大字段,频繁的查询数据库的大字段会导致数据库访问压力变大,访问速度变慢。
表业务说明: 商品表中的id与商品详情表中的ID是一致的。
2.1.4 编辑ItemDesc POJO对象(common中)
package com.jt.pojo;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.experimental.Accessors;
@TableName("tb_item_desc")
@Data
@Accessors(chain = true)
public class ItemDesc extends BasePojo {
/* item(商品表)中的id与ItemDesc(商品详情)中的Id应该保持一致,
* 所以商品详情表的主键不能设置自增。
*/
@TableId //只标识主键 不能自增.
private Long itemId;
private String itemDesc;
}
2.1.5 编辑ItemDescMapper接口
package com.jt.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.jt.pojo.ItemDesc;
public interface ItemDescMapper extends BaseMapper<ItemDesc> {
}
2.2 重构商品新增(2张表)
2.2.1 商品详情页面分析
商品描述实际上就是itemDesc属性,看似存的图片实际上存的是整个html标签。该字段在数据库中属于商品详情表。
2.2.2 重新编译ItemController
@RequestMapping("/save")
/*商品详情表有4个字段:id itemDesc 创建时间 修改时间,而页面只会接收itemDesc属性,所以其它字段在入库
* 时要处理一下。*/
public SysResult saveItem(Item item, ItemDesc itemDesc){
itemService.saveItem(item,itemDesc);
return SysResult.success();
}
2.2.3 重新编辑ItemService
这个id应该是商品(item)入库时才会生成,按照对象的内存规则item执行完,成后和itemDesc没有关系了item.getId()应该为空,但为什么这个地方有值呢?
mp底层封装了通过2个属性动态回显的sql.
那么该如何动态的回显主键信息呢?
1.写sql方式:通过2个属性,可以写在xml也可以写在注解方式的SQL上。 2.MP的方式:实现数据入库操作,MP会自动的实现主键信息的回显(这个地方直接可以获取,详情查看第三阶段)。
service层写几个:看业务是否为同一个。
@Override
@Transactional //控制事务,多张表入库
public void saveItem(Item item, ItemDesc itemDesc) {
/*思考:如果每次编译数据库·每次都需要操作公共的属性(设置创造和更新入库的时间),
* 如何完成自动填充功能?
* 属性自动填充功能
*/
Date date =new Date();
//item.setStatus(1).setCreated(date).setUpdated(new Date());//更新时间就是创造时间(取值刚存进数据库的创造时间。)
item.setStatus(1);
itemMapper.insert(item);
/*这个id应该是商品(item)入库时才会生成,按照对象的内存规则item执行完
*成后和itemDesc没有关系了item.getId()应该为空,但为什么这个地方有值呢?
* mp底层封装了通过2个属性动态回显的sql.
*
* 那么该如何动态的回显主键信息呢?
* 1.写sql方式:通过2个属性,可以写在xml也可以写在注解方式的SQL上。
* 2.MP的方式实现数据入库操作,MP会自动的实现主键信息的回显.(底层封装)
* */
itemDesc.setItemId(item.getId());
itemDescMapper.insert(itemDesc);
}
如:普通方式。
访问测试:
2.3 重构更新(商品详情数据回显)
2.3.1 页面分析
1).js分析
可以看到回显商品数据没有发送ajax请求,但是回显商品详情数据发送了ajax请求
// 加载商品描述
$.getJSON('/item/query/item/desc/'+data.id,function(_data){
if(_data.status == 200){
//动态获取商品详情信息
itemEditEditor.html(_data.data.itemDesc);
}
});
2). url分析
2.3.2 编辑ItemController
/**
* 根据ItemId查询ItemDesc对象
* url:http://localhost:8091/item/query/item/desc/1474391989
* 参数: 商品的id(因为这里把参数id写到了url地址栏里,所以用resful风格来接收)
* 返回值: SysResult对象
*/
@RequestMapping("/query/item/desc/{itemId}")
public SysResult findItemDescById(@PathVariable Long itemId){
ItemDesc itemDesc = itemService.findItemDescById(itemId);
return SysResult.success(itemDesc); //200 返回业务数据
}
2.3.3 编辑ItemService
@Override
public ItemDesc findItemDescById(Long itemId) {
return itemDescMapper.selectById(itemId);
}
2.3.4 页面效果展现
2.4 重构更新(商品更新后提交)
2.4.1 编译ItemController
/**
* 业务说明: 商品修改操作
* url: /item/update
* 参数: 整个form表单
* 返回值: SysResult对象
*/
@RequestMapping("/update")
public SysResult updateItem(Item item,ItemDesc itemDesc){
itemService.updateItem(item,itemDesc);
return SysResult.success();
}
2.4.2 编译ItemService
//商品更新
@Transactional
@Override
public void updateItem(Item item, ItemDesc itemDesc) {
itemMapper.updateById(item);
itemDesc.setItemId(item.getId());
itemDescMapper.updateById(itemDesc);
}
3 重构删除模块
@Transactional
@Override
public void deleteItems(Long[] ids) {
//1.mp的方式实现删除
List<Long> longList = Arrays.asList(ids);//数组转化为集合
//点击删除一次性把商品和商品详情一次性删除,所以这里直接删除即可。
itemMapper.deleteBatchIds(longList);//删除商品表数据
itemDescMapper.deleteBatchIds(longList);//删除详情表数据(因为id相同所以这里传值也相同)
/*2.手动完成批量删除的操作.... 5分钟
itemMapper.deleteItems(ids);*/
}