原代码
优化这段代码,要求是发现是相同图片时就不上传文件到磁盘
public ResultVO uploadFile(MultipartFile file) throws IOException {
String originalFilename = file.getOriginalFilename();//文件全名
String mainName = FileNameUtil.mainName(originalFilename);//截取文件名称
String type = FileNameUtil.extName(originalFilename);//截取文件类型
long size = file.getSize();
// 定义一个文件唯一的标识码
String fileUUID = IdUtil.fastSimpleUUID() + StrUtil.DOT + type;
File uploadFile = new File(fileUploadPath + fileUUID);
// 判断配置的文件目录是否存在,若不存在则创建一个新的文件目录
File parentFile = uploadFile.getParentFile();
if (!parentFile.exists()) {
parentFile.mkdirs();
}
String url;
// 获取文件的md5标识
String md5 = SecureUtil.md5(file.getInputStream());
// 从数据库查询是否存在相同的记录
Example example = new Example(Files.class);
Example.Criteria criteria = example.createCriteria();
criteria.andEqualTo("md5", md5);
List<Files> dbFiles = filesMapper.selectByExample(example);
if (dbFiles.size() != 0) {
url = dbFiles.get(0).getFileUrl();
} else {
// 上传文件到磁盘
file.transferTo(uploadFile);
url = "http://localhost:8080/file/" + fileUUID;
}
// 存储数据库
Files saveFile = new Files();
saveFile.setFileName(mainName);
saveFile.setFileType(type);
saveFile.setFileSize(size / 1024); // 单位 kb
saveFile.setFileUrl(url);
saveFile.setMd5(md5);
saveFile.setFileStatus(true);
saveFile.setIsDelete(false);
saveFile.setFileRegtime(new Date());
saveFile.setFileModtime(new Date());
int i = filesMapper.insertUseGeneratedKeys(saveFile);
if (i > 0) {
return new ResultVO(ResStatus.OK, "上传数据库成功!", url);
} else {
return new ResultVO(ResStatus.NO, "上传数据库失败!", null);
}
}
AI :针对相同文件不重复上传的优化,可以先根据文件的 MD5 值查询数据库中是否存在相同的记录。如果存在,则直接从数据库中获取已有的文件 URL;如果不存在,则上传文件,并将文件信息存储到数据库中。
下面是改进后的代码:
public ResultVO uploadFile(MultipartFile file) throws IOException {
String originalFilename = file.getOriginalFilename();//文件全名
String mainName = FileNameUtil.mainName(originalFilename);//截取文件名称
String type = FileNameUtil.extName(originalFilename);//截取文件类型
long size = file.getSize();
// 获取文件的md5标识
String md5 = SecureUtil.md5(file.getInputStream());
// 从数据库查询是否存在相同的记录
Example example = new Example(Files.class);
Example.Criteria criteria = example.createCriteria();
criteria.andEqualTo("md5", md5);
List<Files> dbFiles = filesMapper.selectByExample(example);
String url;
if (!dbFiles.isEmpty()) {
url = dbFiles.get(0).getFileUrl();
} else {
// 定义一个文件唯一的标识码
String fileUUID = IdUtil.fastSimpleUUID() + StrUtil.DOT + type;
File uploadFile = new File(fileUploadPath + fileUUID);
// 判断配置的文件目录是否存在,若不存在则创建一个新的文件目录
File parentFile = uploadFile.getParentFile();
if (!parentFile.exists()) {
parentFile.mkdirs();
}
// 上传文件到磁盘
file.transferTo(uploadFile);
url = "http://localhost:8080/file/" + fileUUID;
// 存储数据库
Files saveFile = new Files();
saveFile.setFileName(mainName);
saveFile.setFileType(type);
saveFile.setFileSize(size / 1024); // 单位 kb
saveFile.setFileUrl(url);
saveFile.setMd5(md5);
saveFile.setFileStatus(true);
saveFile.setIsDelete(false);
saveFile.setFileRegtime(new Date());
saveFile.setFileModtime(new Date());
int i = filesMapper.insertUseGeneratedKeys(saveFile);
if (i <= 0) {
throw new RuntimeException("上传数据库失败!");
}
}
return new ResultVO(ResStatus.OK, "上传成功!", url);
}
这样,如果上传的文件在数据库中已经存在,则可以直接返回已有的文件 URL,而不需要重复上传。这样既可以避免重复上传相同文件的问题,又能提高文件上传的效率。
笔记:
!dbFiles.isEmpty()为什么用isEmpty判断而不用size()方法
使用 isEmpty() 方法可以更加清晰地表达代码的语义,因为这个方法的作用就是判断集合是否为空。而 size() 方法则返回集合中元素的数量,虽然也可以用来判断集合是否为空(当集合大小为0时),但是这样做显得不太自然,容易让人产生误解。因此,在这个场景下选择使用 isEmpty() 方法更加合理。
另外,需要注意的是 List 接口中的 isEmpty() 方法实现方式为直接判断 size() 是否等于 0,因此在性能上两种方式是等价的。
**ArrayList.java**
public boolean isEmpty() {
return size == 0;
}