mysql的创建修改时间的自动填充,图片上传

字段自动填充

一、首先我们需要在表上创建相应的字段

在这里插入图片描述

1:值得注意的是这个类型,datetime,还有别的操作时间的类型,这个区别还是有一点,详细可以百度一下,此处就不写了

二、标准的java实体映射类肯定是需要的

在这里插入图片描述

1:这第一个注解:@DateTimeFormat,就是指定这个时间格式,这个与上述的datetime还是有一点关系的,可以自己百度,尝试一下别的

@DateTimeFormat只能用在**【表单键值对】**这种提交方式,而且只能格式化前端->后端数据,不能用于json格式的提交方式,也不能用于后端->前端的格式化

@JsonFormat只能用在**【json格式】**这种提交方式,而且既能格式化前端-后端的数据,也能格式化后端->前端的数据
重点:当前端传来json串,后台用@ReuqestBody接收,必须用@JsonFormat 规定接收的时间格式。上面直接这么使用,在我们中国来讲和我们的北京时间,会相差8个小时,因为我们是东八区(北京时间)。

所以我们在格式化的时候要指定时区(timezone )

public class Param {
    @JsonFormat(shape = JsonFormat.Shape.STRING , pattern = "yyyy-MM-dd HH:mm:ss", , timezone = "Asia/Shanghai")
    private Date date;
}

2:关键是第二个注解:@TableField,相当于表达这是什么操作,然后与下文形成对应

3:注意:!!!! 此处的Date 是java.util.Date,不要导sql的包,sql也有一个Date,具体我也没研究为啥,如果导了这个sql包,会报错

三、注解有了还不行,还要做最后一步,实现MetaObjectHandler接口

package com.cy.pj.common.config;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.cy.pj.common.api.ShiroUtils;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;

import java.util.Date;

/**
 * 配置字段自动填充
 * 自定义MyMetaObjectHandler 字段自动填充处理类实现 MetaObjectHandler
 */

@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
    /**
     * fieldName:实体映射类的属性名
     * 第二个参数为值
     * 第三个参数:元数据对象
     * @param metaObject
     */
     
     //新增时填充
    @Override
    public void insertFill(MetaObject metaObject) {
        //按名称设置字段值
        this.setFieldValByName("createdTime", new Date(), metaObject);  //创建时间
        this.setFieldValByName("modifiedTime", new Date(), metaObject); //修改时间
        this.setFieldValByName("createdUser", ShiroUtils.getUsername(), metaObject);  //创建人
        this.setFieldValByName("modifiedUser", ShiroUtils.getUsername(), metaObject); //修改人


    }
	//修改时填充
    @Override
    public void updateFill(MetaObject metaObject) {
        this.setFieldValByName("modifiedTime", new Date(), metaObject);  //修改时间
        this.setFieldValByName("modifiedUser", ShiroUtils.getUsername(), metaObject); //修改人
    }
}

1:此处需要注意,需要交给spring容器管理

2:实现这个接口的两个方法,insertFill和updateFill

3:测试即可实现自动填充,当然,既然是自动填充,所以我们不需要传值

四、如果出现时间点不一样的情况,一般是差8个小时[东八区],那么这个时候,我们就需要添加一点配置

复制代码

spring:

  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    username: root
    password: root

#关键操作,数据库名后面添加:?

serverTimezone=GMT%2B8&useSSL=false&useUnicode=true&characterEncoding=UTF-8
    url: jdbc:mysql://192.168.27.212:3306/mydata?serverTimezone=GMT%2B8&useSSL=false&useUnicode=true&characterEncoding=UTF-8
  jackson:
  #时间的格式
    date-format: yyyy-MM-dd HH:mm:ss
  #时间+8小时
    time-zone: GMT+8 

复制代码

五、如果测试还是不行,配置文件不起作用,那就只能写死时间,使用时间的工具类【此操作可能导致多台设备添加的时间不一致,谨慎使用】

1、引入依赖

    <dependency>
        <groupId>joda-time</groupId>
        <artifactId>joda-time</artifactId>
    </dependency>

2、在实现MetaObjectHandler接口的类中,要把new Date();改掉

 1 @Component
 2 public class MyObjectHandler implements MetaObjectHandler {
 3     @Override
 4     public void insertFill(MetaObject metaObject) {
 5         /**
 6          * fieldName:实体映射类的属性名
 7          * 第二个参数:属性值
 8          * 第三个:元数据对象
 9          * DateTime.now().plusHours(13).toDate():时间+13小时,
10          * 这个13小时只是我这里差的值,差多少改多少
11          */
12         this.setFieldValByName("createTime", DateTime.now().plusHours(13).toDate(),metaObject);
13         this.setFieldValByName("updateTime",DateTime.now().plusHours(13).toDate(),metaObject);
14     }
15 
16     @Override
17     public void updateFill(MetaObject metaObject) {
18         this.setFieldValByName("updateTime",DateTime.now().plusHours(13).toDate(),metaObject);
   }
 }

六、以上的写死时间的操作,纯属个人娱乐操作,没有实际应用意义,只有配置文件生效的那个操作,才是最好的操作,传值的时候,什么都不需要写,对象传值的话,直接忽略它就好

=====================================================

图片上传

1.准备ImageVO对象

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 {

    //{"error":0,"url":"图片的保存路径","width":图片的宽度,"height":图片的高度}
    private Integer error;  //错误信息   0程序运行正常    1.文件上传有误.
    private String url;     //图片访问的虚拟路径
    private Integer width;  // >0
    private Integer height; // >0

    //设定上传失败的方法
    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.编辑FileController

通过MultipartFile(多部分文件)获取上传的文件
 /**
     * 实现文件上传
     * url地址: http://localhost:8091/pic/upload?dir=image
     * 参数:    uploadFile: 文件的字节信息.
     * 返回值:  {"error":0,"url":"图片的保存路径","width":图片的宽度,"height":图片的高度}
     *          ImageVO对象...
     */
    @RequestMapping("/pic/upload")
    public ImageVO upload(MultipartFile uploadFile){

        return fileService.upload(uploadFile);
    }

3.编辑FileServiceImpl (上传地址写死了,图片url为虚假路径,后面优化)

图像数据读写利器 -- ImageIO (处理图像的API)
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 String rootDirPath = "D:/JT-SOFT/images";

    //1.2 准备图片的集合  包含了所有的图片类型.
    private static Set<String> imageTypeSet;
    static {
        imageTypeSet = new HashSet<>();
        imageTypeSet.add(".jpg");
        imageTypeSet.add(".png");
        imageTypeSet.add(".gif");
    }


    /**
     * 完善的校验的过程
     * 1. 校验是否为图片
     * 2. 校验是否为恶意程序
     * 3. 防止文件数量太多,分目录存储.
     * 4. 防止文件重名
     * 5. 实现文件上传.
     * @param uploadFile
     * @return
     */
    @Override
    public ImageVO upload(MultipartFile uploadFile) {
        //1.校验图片类型  jpg|png|gif..JPG|PNG....
        //1.1 获取当前图片的名称 之后截取其中的类型.   abc.jpg
        String fileName = uploadFile.getOriginalFilename();
        int index = fileName.lastIndexOf(".");
        String fileType = fileName.substring(index);
        //将数据转化为小写
        fileType = fileType.toLowerCase();
        //1.3 判断图片类型是否正确.
        if(!imageTypeSet.contains(fileType)){
            //图片类型不匹配
            return ImageVO.fail();
        }

        //2.校验是否为恶意程序 根据宽度/高度进行判断
        try {
            //2.1 利用工具API对象 读取字节信息.获取图片对象类型
            BufferedImage bufferedImage = ImageIO.read(uploadFile.getInputStream());
            //2.2 校验是否有宽度和高度
            int width = bufferedImage.getWidth();
            int height = bufferedImage.getHeight();
            if(width==0 || height==0){
                return ImageVO.fail();
            }

            //3.分目录存储  yyyy/MM/dd 分隔
            //3.1 将时间按照指定的格式要求 转化为字符串.
            String dateDir = new SimpleDateFormat("/yyyy/MM/dd/")
                             .format(new Date());
            //3.2 拼接文件存储的目录对象
            String fileDirPath = rootDirPath + dateDir;
            File dirFile = new File(fileDirPath);
            //3.3 动态创建目录
            if(!dirFile.exists()){
                dirFile.mkdirs();
            }

            //4.防止文件重名  uuid.jpg 动态拼接
            //4.1 动态生成uuid  实现文件名称拼接  名.后缀
            String uuid =
                    UUID.randomUUID().toString().replace("-", "");
            String realFileName = uuid + fileType;

            //5 实现文件上传
            //5.1 拼接文件真实路径 dir/文件名称.
            String realFilePath = fileDirPath + realFileName;
            //5.2 封装对象  实现上传
            File realFile = new File(realFilePath);
            uploadFile.transferTo(realFile);

            //实现文件上传成功!!!!
            String url = "https://img14.360buyimg.com/n0/jfs/t1/45882/22/7027/53284/5d49358aE9c25c1bd/fb7365463f6a1a7b.jpg";
            return ImageVO.success(url,width,height);
        } catch (IOException e) {
            e.printStackTrace();
            return ImageVO.fail();
        }
    }
}


4. 文件上传优化

1.1 url优化
说明: 如果需要通过网络虚拟路径访问服务器.则应该按照如下的配置实现.

1.本地磁盘路径: D:\JT-SOFT\images\2020\09\30\a.jpg
2.网络虚拟路径: http://image.jt.com\2020\09\30\a.jpg

1.2 编辑pro配置文件

在这里插入图片描述
1.3 完成属性的动态赋值

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("classpath:/properties/images.properties") //容器动态加载指定的配置文件
public class FileServiceImpl implements FileService{

    //由于属性的值后期可能会发生变化,所以应该动态的获取属性数据. 利用pro配置文件
    @Value("${image.rootDirPath}")
    private String rootDirPath;             //   = "D:/JT-SOFT/images";
    @Value("${image.urlPath}")
    private String urlPath;                 // = "http://image.jt.com";

    //1.2 准备图片的集合  包含了所有的图片类型.
    private static Set<String> imageTypeSet;
    static {
        imageTypeSet = new HashSet<>();
        imageTypeSet.add(".jpg");
        imageTypeSet.add(".png");
        imageTypeSet.add(".gif");
    }


    /**
     * 完善的校验的过程
     * 1. 校验是否为图片
     * 2. 校验是否为恶意程序
     * 3. 防止文件数量太多,分目录存储.
     * 4. 防止文件重名
     * 5. 实现文件上传.
     * @param uploadFile
     * @return
     */
    @Override
    public ImageVO upload(MultipartFile uploadFile) {
        //0.防止有多余的空格 所以先做去空格的处理
        rootDirPath.trim();
        urlPath.trim();

        //1.校验图片类型  jpg|png|gif..JPG|PNG....
        //1.1 获取当前图片的名称 之后截取其中的类型.   abc.jpg
        String fileName = uploadFile.getOriginalFilename();
        int index = fileName.lastIndexOf(".");
        String fileType = fileName.substring(index);
        //将数据转化为小写
        fileType = fileType.toLowerCase();
        //1.3 判断图片类型是否正确.
        if(!imageTypeSet.contains(fileType)){
            //图片类型不匹配
            return ImageVO.fail();
        }

        //2.校验是否为恶意程序 根据宽度/高度进行判断
        try {
            //2.1 利用工具API对象 读取字节信息.获取图片对象类型
            BufferedImage bufferedImage = ImageIO.read(uploadFile.getInputStream());
            //2.2 校验是否有宽度和高度
            int width = bufferedImage.getWidth();
            int height = bufferedImage.getHeight();
            if(width==0 || height==0){
                return ImageVO.fail();
            }

            //3.分目录存储  yyyy/MM/dd 分隔
            //3.1 将时间按照指定的格式要求 转化为字符串.
            String dateDir = new SimpleDateFormat("/yyyy/MM/dd/")
                             .format(new Date());
            //3.2 拼接文件存储的目录对象
            String fileDirPath = rootDirPath + dateDir;
            File dirFile = new File(fileDirPath);
            //3.3 动态创建目录
            if(!dirFile.exists()){
                dirFile.mkdirs();
            }

            //4.防止文件重名  uuid.jpg 动态拼接
            //4.1 动态生成uuid  实现文件名称拼接  名.后缀
            String uuid =
                    UUID.randomUUID().toString().replace("-", "");
            String realFileName = uuid + fileType;

            //5 实现文件上传
            //5.1 拼接文件真实路径 dir/文件名称.
            String realFilePath = fileDirPath + realFileName;
            //5.2 封装对象  实现上传
            File realFile = new File(realFilePath);
            uploadFile.transferTo(realFile);

            //实现文件上传成功!!! http://image.jt.com\2020\09\30\a.jpg
            String url = urlPath + dateDir + realFileName;
            return ImageVO.success(url,width,height);
        } catch (IOException e) {
            e.printStackTrace();
            return ImageVO.fail();
        }
    }
}

5.MultipartFile接口常用方法详解

说明:这个类一般是用来接收前台传过来的文件;
MultipartFile是spring类型,代表HTML中form data方式上传的文件,包含二进制数据+文件名称。

<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>

在这里插入图片描述
在这里插入图片描述

概述: MultipartFile为org.springframework.web.mutipart包下的一个类,也就是说如果想使用MultipartFile这个类就必须引入spring框架,换句话说,如果想在项目中使用MultipartFile这个类,那么项目必须要使用spring框架才可以,否则无法引入这个类。MultipartFile翻译成中文来讲就是“多组件的文档”,不用太在乎他的中文含义,一般来讲使用MultipartFile这个类主要是来实现以表单的形式进行文件上传功能。

常用方法:
(1)、getName方法

      getName方法获取的是前后端约定的传入文件的参数的名称,在SpringBoot后台中则是通过@Param("uploadFile") 注解定义的内容

(2)、getOriginalFileName方法

     getOriginalFileName方法获取的是文件的完整名称,包括文件名称+文件拓展名。

(3)、getContentType方法

     getContentType方法获取的是文件的类型,注意是文件的类型,不是文件的拓展名。

(4)、isEmpty方法

     isEmpty方法用来判断传入的文件是否为空,如果为空则表示没有传入任何文件。

(5)、getSize方法

     getSize方法用来获取文件的大小,单位是字节。

(6)、getBytes方法

     getBytes方法用来将文件转换成一种字节数组的方式进行传输,会抛出IOException异常。

(7)、getInputStream方法

     getInputStream方法用来将文件转换成输入流的形式来传输文件,会抛出IOException异常。

(8)、transferTo方法

     transferTo方法用来将接收文件传输到给定目标路径,会抛出IOException、IllegalStateException异常。该方法在实际项目开发中使用较少。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值