SpringBoot part4 day06

@Mapper 接口交给Spring容器管理
也可以在主启动类上添加@MapperScan(" ")
SpringBoot part4 day06

1.实现商品详情的展现

1.1业务说明

一般用户查询商品时,只需要展现商品想关信息即可,如果用户点击某个商品时点击详情才会显示商品详情信息,因为商品详情属于大字段信息,检索相对较慢,浪费性能

表设计说明:
1.tb_item商品表
2.tb_item_desc商品详情表
SpringBoot part4 day06
1.1.1编辑商品详情pojo对象:

package com.jt.pojo;

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;

@Data
@Accessors(chain =true)
@NoArgsConstructor
@AllArgsConstructor
@TableName("tb_item_desc")
public class ItemDesc extends BasePojo{
    /**
     * 商品id需要与item的id有对应关系,不能随意自增
     * */
    @TableId
    private Long itemId;   //商品ID
    private String itemDesc; //商品详情



}

1.2富文本编辑器

1.2.1入门案例
SpringBoot part4 day06
SpringBoot part4 day06
底层实现
SpringBoot part4 day06
1.2.2新增商品及商品详情
controller

	/**                                                                  
	 * 商品d的新增业务的实现	 * */                                                
	@RequestMapping("/save")                                             
	public SysResult doSaveObject(Item item, ItemDesc itemDesc){         
		     	itemService.saveItem(item,itemDesc);                     
		     		return SysResult.success();                          
                                                                      
	/*	try{                                                             
                                                                      
			itemService.saveItem(item,itemDesc);                         
			return SysResult.success();                                  
		}catch(Exception e){                                             
			e.printStackTrace();                                         
			return SysResult.fail();                                     
		}                                                                
		*/                                                               
                                                                      
	}                                                                    ```

```java
@Override
	@Transactional
	public void saveItem(Item item , ItemDesc itemDesc) {
		//Date date=new Date();
		item.setStatus(1);//.setCreated(date).setUpdated(date);
		//MP用法:如果完成主键自增,自动实现数据的回显
		itemMapper.insert(item);
		//获取主键的信息
		itemDesc.setItemId(item.getId());
		itemDescMapper.insert(itemDesc );

	}

1.3商品详情信息的回显

SpringBoot part4 day06
SpringBoot part4 day06

//回显数据
        			var data = $("#itemList").datagrid("getSelections")[0];
        			data.priceView = KindEditorUtil.formatPrice(data.price);
        			$("#itemeEditForm").form("load",data);
        			
        			// 加载商品描述
        			//_data = SysResult.ok(itemDesc)
        			$.getJSON('/item/query/item/desc/'+data.id,function(_data){
        				if(_data.status == 200){
        					//UM.getEditor('itemeEditDescEditor').setContent(_data.data.itemDesc, false);
        					itemEditEditor.html(_data.data.itemDesc);
        				}
        			});
        			

1.3.1controller

/**
	 * 商品详情信息的回显
	 * 
	 * */
	@RequestMapping("/query/item/desc/{itemId}")
	public SysResult findItemDescById(@PathVariable Long itemId){
       ItemDesc itemDesc=itemService.findItemDescById(itemId);
       //业务调用传值到页面
       return SysResult.success(itemDesc);

	}

itemServiceImpl

@Override
	public ItemDesc findItemDescById(Long itemId) {

		return itemDescMapper.selectById(itemId);
	}

1.4重构商品更新

controller

@RequestMapping("/update")
	public SysResult doUpdateItem(Item item,ItemDesc itemDesc){
		itemService.updateItem(item,itemDesc);
		return SysResult.success();
	}

itemServiceImpl

@Override
	@Transactional
	public void updateItem(Item item,ItemDesc itemDesc) {
		itemMapper.updateById(item);
		itemDesc.setItemId(item.getId());
		itemDescMapper.updateById(itemDesc);
	}

1.5商品的删除

ItemController

@RequestMapping("/delete")
	public SysResult doDeleteItemByIds(Integer[] ids){

		itemService.deleteByIds(ids);
		return new SysResult().success();
	}

ItemServiceImpl

@Override
	@Transactional
	public void deleteByIds(Integer[] ids) {
		itemMapper.deleteItemByIds(ids);
		itemDescMapper.deleteBatchIds(Arrays.asList(ids));
	}

2.文件上传

2.1文件上传案例

enctype=“multipart/form-data” 开启多媒体传递,不然只能传递文本

<%@ 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">
<title>Insert title here</title>
</head>
<body>
	<h1>实现文件上传</h1>
	<!--enctype="开启多媒体标签"  -->
	<form action="http://localhost:8091/file" method="post" 
	enctype="multipart/form-data">
		<input name="fileImage" type="file" />
		<input type="submit" value="提交"/>
	</form>
</body>
</html>

SpringBoot part4 day06

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;

@RestController
public 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:/tena/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 "文件上传成功!!!";
    }




}

页面url分析:

SpringBoot part4 day06
SpringBoot part4 day06
SpringBoot part4 day06
SpringBoot part4 day06
定义请求的参数和url
SpringBoot part4 day06
返回值JSON结构

{“error”:0,“url”:“图片的保存路径”,“width”:图片的宽度,“height”:图片的高度}
参数说明: 0代表是一张图片,如果是0,前台才可以解析并显示。1代表不是图片,
不显示如果不设置宽度和高度,则默认用图片原来的大小,所以不用设置

package com.jt.vo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

@Data
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
public class ImageVo {
    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 height,Integer width){

       return new ImageVo(0,url,width,height);
    }
     public static ImageVo success(String url){

       return new ImageVo(0,url,null,null);
    }


}

package com.jt.service;

import com.jt.vo.ImageVo;
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
public class FileServiceImpl implements FileService{
    //定义图片类型
    private static Set<String> imageTypeSet=new HashSet<>();
    private String localDirPath="D:/tena/images";//定义本地磁盘目录
    static{
        imageTypeSet.add(".jpg");
        imageTypeSet.add(".png");
        imageTypeSet.add(".gif");

    }
    /**
     * 1.校验文件的有效性
     * 2.检验文件是否为恶意程序(木马.exe).jpg
     * 3.提高用户检索图片的效率   分目录存储
     * 4.为了防止重名图片的提交 自定义文件名称
     * 5.实现图片的物理上传 本地磁盘中
     * 6.准备一个访问图片的虚拟路径
     * @param uploadFile
     * @return ImageVo
     * */

    @Override
    public ImageVo upload(MultipartFile uploadFile)  {
        //1.利用图片类型   利用正则表达式进行校验  利用集合进行校验
        //1.1获取图片的名称
        String fileName=uploadFile.getOriginalFilename();
        fileName=fileName.toLowerCase();//将所有的字母都小写
        //1.2获取图片的类型
        int index=fileName.lastIndexOf(".");
        String fileType=fileName.substring(index);
        if(!imageTypeSet.contains(fileType)){//如果类型不匹配
            return ImageVo.fail();//图片上传失败
        }
        //2.如何判断文件是否为恶意程序?文件是否有图片的特有属性
        //2.1将上传的文件类型利用图片的API进行转化,如果转化不成功则一定不是图片
        try {
            BufferedImage bufferedImage= ImageIO.read(uploadFile.getInputStream());
            //2.2检验是否有图片的特有属性  高度和宽度
            int width=bufferedImage.getWidth();
            int height=bufferedImage.getHeight();
            //2.3检验宽度和高度是否有值
            if(width==0||height==0){
                return ImageVo.fail();
            }
        } catch (IOException e) {
            e.printStackTrace();
            return ImageVo.fail();
        }
        //3.实现分目录存储
        //方案1:利用hash之后每隔2-3位截取之后拼接
        //方案2:以时间为单位进行分割 /yyyy/MM/dd
        //3.1利用工具API将时间转化为指定的格式
        String datePath=new SimpleDateFormat("/yyyy/MM/dd/").format(new Date());
        //3.2动态生成文件目录  两部分=根目录+时间目录
        String localDir=localDirPath+datePath;
        //3.3判断目录是否存在,如果不存在则新建目录
        File dirFile=new File(localDir);
        if(!dirFile.exists()){
            dirFile.mkdirs();//如果不存在则新建目录
        }
        //4.防止文件重名,需要自定义文件名称
        //4.1生成uuid
        String uuid= UUID.randomUUID().toString().replace("-", "");
        //4.2动态生成文件名称 uuid+.jpg
        String uuidFileName=uuid+fileType;
        //5.实现文件上传 准备文件全路径  目录+文件名称
        String realFilePath=localDir+uuidFileName;
        //5.1封装文件真实对象
        File imageFile=new File(realFilePath);
        try {
            uploadFile.transferTo(imageFile);

        } catch (IOException e) {
            e.printStackTrace();
            return ImageVo.fail();
        }
        //6.暂时使用京东图片代替
        //检查文件上传业务调用是否正确
        String url="https://img30.360buyimg.com/sku/jfs/t1/128256/32/4631/320177/5ee24409E0057d015/2d30b869688968d2.gif";

        return ImageVo.success(url);
    }
}

IDEA光标问题

选中代码每一行末尾都有光标:
SpringBoot part4 day06
在代码编辑区用鼠标单击右键把 Column Selection Model 前面的勾去掉就ok了
SpringBoot part4 day06

端口占用

cmd----》netstat -ano-----》(找到端口对应的进程号)taskkill -f -pid 进程号

上一篇:ansible剧本--day06--搭建wordpress


下一篇:自学Java之day06_类与对象、封装、构造方法