1.实现商品详情展示
1.1 业务阐明
个别用户查问商品时,只须要展示商品相干信息即可,如果用户点击某个商品时才会展示商品详情信息,因为商品详情是大字段信息,所以检索绝对较慢,节约性能.
表设计说明:
1.tb_item 商品表
2.tb_item_desc 商品详情表
一个商品只有一个详情信息,所以item表与itemDesc一对一.
1.2 商品详情表设计
1.3 编辑ItemDesc
package com.jt.pojo;import com.baomidou.mybatisplus.annotation.IdType;import com.baomidou.mybatisplus.annotation.TableId;import com.baomidou.mybatisplus.annotation.TableName;import lombok.AllArgsConstructor;import lombok.Data;import lombok.NoArgsConstructor;import lombok.experimental.Accessors;@TableName("tb_item_desc")@Data@NoArgsConstructor@AllArgsConstructor@Accessors(chain = true)public class ItemDesc extends BasePojo{ @TableId private Long itemId; //商品ID 与item表中的数据统一. private String itemDesc; //商品详情}
1.4 富文本编辑器介绍
1.4.1 入门案例
1.5 重构商品新增
1.5.1 业务阐明
因为商品新增是将Item/ItemDesc对象一起新增,所以须要实现2张表的入库操作.
1.5.2 编辑ItemController
/** * 业务需要: 实现商品新增操作 * url: http://localhost:8091/item/save * 参数: 整个表单进行提交 应用对象接管 * 返回值: 零碎返回值对象 */ @RequestMapping("/save") @Transactional public SysResult saveItem(Item item, ItemDesc itemDesc) { itemService.saveItem(item,itemDesc); return SysResult.success(); }
1.5.3 编辑ItemService
@Override@Transactional//开启事务管制public void saveItem(Item item, ItemDesc itemDesc) { //MP用法:如果实现主键自增,则主动的实现数据的回显!!! itemMapper.insert(item); //获取主键信息 itemDesc.setItemId(item.getId()); itemDescMapper.insert(itemDesc); }
1.6 商品详情展示
1.6.1 页面剖析
1.6.2 页面JS剖析
1.6.3 编辑ItemController
@RequestMapping("/query/item/desc/{itemId}")public SysResult findItemDescById(@PathVariable Long itemId){ ItemDesc itemDesc=itemService.findItemDescById(itemId); return SysResult.success(itemDesc);}
1.6.4 编辑ItemService
@Overridepublic ItemDesc findItemDescById(Long itemId) { return itemDescMapper.selectById(itemId);}
1.6.5 页面成果展示
1.7 重构商品更新
1.7.1 业务阐明
当用户点击商品更新时,应该实现2张表的数据更新操作. 更新Item/更新ItemDesc对象
1.7.2 编辑ItemController
/** * 实现商品编辑 * url地址: /item/update * 申请参数: 整个form表单提交 * 返回值: sysResult对象 */@RequestMapping("/update")public SysResult updateItem(Item item,ItemDesc itemDesc) { itemService.updateItem(item,itemDesc); return SysResult.success();}
1.7.3 编辑ItemService
@Override@Transactional //管制事务public void updateItem(Item item, ItemDesc itemDesc) { itemMapper.updateById(item); //补全数据 itemDesc.setItemId(item.getId()); itemDescMapper.updateById(itemDesc);}
1.8 商品删除操作
1.8.1 编辑ItemController
/** * 实现商品的删除 * url:/item/delete * 参数:ids * 返回类型:SysResult */@RequestMapping("/delete")public SysResult deleteItems(Long[] ids) { itemService.deleteItems(ids); return SysResult.success();}
1.8.2 编辑ItemService
@Override@Transactionalpublic void deleteItems(Long[] ids) { //形式2手写sql形式实现删除 itemMapper.deleteItems(ids); //商品详情信息 List<Long> longIds= Arrays.asList(ids); itemDescMapper.deleteBatchIds(longIds);}
2 文件上传
2.1 文件上传入门案例
2.1.1 页面标识
2.1.2 文件上传入门案例
package com.jt.controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import org.springframework.web.multipart.MultipartFile;import java.io.File;import java.io.IOException;import java.io.InputStream;@RestControllerpublic class FileController { /** * url地址: http://localhost:8091/file * 参数: 文件信息 fileImage * 返回值: String */ @RequestMapping("/file") public String file(MultipartFile fileImage) throws IOException { //1.获取图片名称 String name = fileImage.getOriginalFilename(); //2.定义文件目录 String fileDirPath = "D:/JT-SOFT/images"; //3.创立目录 File fileDir = new File(fileDirPath); if(!fileDir.exists()){ fileDir.mkdirs(); } //4.生成文件的全门路 String filePath = fileDirPath+"/"+name; File imageFile = new File(filePath); //5.实现文件上传 fileImage.transferTo(imageFile); return "文件上传胜利!!!"; }}
2.2 实现文件上传
2.2.1 页面URL剖析
2.2.2 申请参数
2.2.3 编辑VO对象
{“error”:0,“url”:“图片的保留门路”,“width”:图片的宽度,“height”:图片的高度}
package com.jt.vo;import lombok.AllArgsConstructor;import lombok.Data;import lombok.NoArgsConstructor;import lombok.experimental.Accessors;@Data@Accessors(chain = true)@NoArgsConstructor@AllArgsConstructorpublic class ImageVO { //{"error":0,"url":"图片的保留门路","width":图片的宽度,"height":图片的高度} private Integer error; // 0 示意文件上传正确 1.上传有误 private String url; //图片浏览的网络地址(虚拟地址) private Integer width; //宽度 private Integer height; //高度 public static ImageVO fail(){ return new ImageVO(1, null, null, null); } public static ImageVO success(String url,Integer width,Integer height){ return new ImageVO(0, url,width, height); }}
2.2.4 编辑FileController
/** * 业务需要: 实现文件上传操作 * url:http://localhost:8091/pic/upload?dir=image * 参数:uploadFile * 返回值: ImageVO对象 */ @RequestMapping("/pic/upload") public ImageVO upload(MultipartFile uploadFile){ return fileService.upload(uploadFile); }
2.2.5 编辑pro配置文件
#配置本地磁盘根目录image.fileDir=E:/images#配置图片服务器地址image.urlPath=http://image.ji.com
2.2.6 编辑FileService
package com.jt.service;import com.jt.vo.ImageVO;import org.springframework.beans.factory.annotation.Value;import org.springframework.context.annotation.PropertySource;import org.springframework.stereotype.Service;import org.springframework.web.multipart.MultipartFile;import javax.imageio.ImageIO;import java.awt.image.BufferedImage;import java.io.File;import java.io.IOException;import java.text.SimpleDateFormat;import java.util.Date;import java.util.HashSet;import java.util.Set;import java.util.UUID;@Service@PropertySource(value="classpath:/properties/image.properties",encoding="UTF-8")public class FileServiceImpl implements FileService { @Value("${image.fileDir}") private String fileDir;//"E:/images" @Value("${image.urlPath}") private String urlPath;//设定域名网址 private static Set<String> typeSet = new HashSet<>(); static { typeSet.add(".jpg"); typeSet.add(".png"); typeSet.add(".gif"); } /** * 业务逻辑:实现文件上传@Override * 步骤: * 1.校验图片的类型 jpg|png|gif....... * 2.校验文件是否为恶意程序... * 3.采纳分目录的构造进行存储 * 4.防止文件重名 UUID * @param uploadFile * @return */ @Override public ImageVO upload(MultipartFile uploadFile) { //一. 校验图片类型 1.利用汇合校验 2.正则表达式 //1.1 获取文件名称 1.jpg 1.JPG} String fileName = uploadFile.getOriginalFilename(); //全副转化为小写 fileName = fileName.toLowerCase(); //1.2 获取文件后缀类型 int index = fileName.lastIndexOf("."); //1.3 .jpg String fileType = fileName.substring(index); //1.4 判断是否为图片类型 if (!typeSet.contains(fileType)) { return ImageVO.fail(); } //二.如果是图片,高度、宽度 //2.1将数据转化图片对象 try { BufferedImage bufferedImage=ImageIO.read(uploadFile.getInputStream()); int width=bufferedImage.getWidth(); int height=bufferedImage.getHeight(); if (width==0||height==0){ return ImageVO.fail(); } //三.实现分目录贮存 //3.1依照/yyyy/MM/dd/的形式进行目录划分 String dateDir=new SimpleDateFormat("/yyyy/MM/dd/").format(new Date()); //E:/images/2020/12/01 String fileDirPath=fileDir+dateDir; File dirFile=new File(fileDirPath); //3.2创立目录 if (!dirFile.exists()){ dirFile.mkdirs(); } //四.实现文件上传 //4.1筹备文件名称 UUID String uuid= UUID.randomUUID().toString().replace("-",""); //4.2动静生成文件名称 String uuidName=uuid+fileType; //4.3实现文件上传 E:images20201202a.jpg File realFile=new File(fileDirPath+uuidName) ; uploadFile.transferTo(realFile); //本地磁盘地址:E:images20201202a.jpg //网络拜访虚拟地址:http://image.ji.com20201202a.jpg String url=urlPath+dateDir+uuidName; return ImageVO.success(url,width,height); } catch (IOException e) { e.printStackTrace(); } return null; }}
2.2.7 代码测试
1.上传图片之后 文件上传的门路.
2.将申请的前缀批改为具体磁盘地址
切换前缀,查看文件是否失常