没有文件服务器,头像存哪里合适
1. 背景
之前有同学私信我说,他的项目只是想存个头像,没有别的文件存储需求,不想去用什么Fastdfs之类的方案搭建文件服务器,有没有更简单且无需后期维护的方案,我喝了一口过期的开水,想了下,还真有,现在就给大家介绍一下。
这个方案就是把头像存在表里,但是要切记,不要存大图,否则会严重影响数据库性能,怎么确保这一点呢,其实只要对上传的图片转成缩略图就可以保证存进去的是小图,这样的话这个方案就比较完美了。
2. 关键步骤梳理
2.1 数据库设计
字段的类型应该是blob, blob是一种二进制存储类型,用来存储图片完全是没问题的
2.2 后端接口
-
Controller
@Operation(summary = "修改头像") @PostMapping("/avatar") public Result<?> updateAvatar(MultipartFile file, @RequestParam("userId") Integer userId) throws IOException, SQLException { // 读取上传的原始图片 BufferedImage originalImage = ImageIO.read(file.getInputStream()); // 创建缩略图 int thumbnailSize = 200; // 计算缩略图的宽度和高度,保持原宽高比例 int newWidth, newHeight; if (originalImage.getWidth() > originalImage.getHeight()) { newWidth = thumbnailSize; newHeight = thumbnailSize * originalImage.getHeight() / originalImage.getWidth(); } else { newWidth = thumbnailSize * originalImage.getWidth() / originalImage.getHeight(); newHeight = thumbnailSize; } // 创建缩略图 BufferedImage thumbnail = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_RGB); Graphics2D graphics2D = thumbnail.createGraphics(); graphics2D.drawImage(originalImage, 0, 0, newWidth, newHeight, null); graphics2D.dispose(); // 裁剪成以图片中心为中心的正方形,因为前端是以正方形显示 int x = 0; int y = 0; int cropSize = Math.min(newWidth, newHeight); if (newWidth > newHeight) { x = (newWidth - cropSize) / 2; } else { y = (newHeight - cropSize) / 2; } thumbnail = thumbnail.getSubimage(x, y, cropSize, cropSize); ByteArrayOutputStream bs = new ByteArrayOutputStream(); ImageIO.write(thumbnail, "jpg", bs); byte[] thumbnailBytes = bs.toByteArray(); userService.updateAvatar(userId,thumbnailBytes); return Result.success(); } @Operation(summary = "查询头像") @GetMapping("/avatar") public Result<?> getAvatar(@RequestParam("userId") Integer userId){ byte[] arvatarData = userService.getAvatar(userId); return Result.success(arvatarData); }
-
Service
@Override public void updateAvatar(Integer userId, byte[] avatar) throws SQLException { log.debug("avatar: " + avatar.length); SerialBlob avatarBlob = new SerialBlob(avatar); userMapper.updateAvatar(userId,avatarBlob); } @Override public byte[] getAvatar(Integer userId) { User user = userMapper.selectById(userId); return user.getAvatarData(); }
-
Mapper
@Update("update wj_user set avatar_data=#{avatarBlob} where id = #{userId}") void updateAvatar(Integer userId, Blob avatarBlob);