没有文件服务器,头像存哪里合适
视频在bilibili:没有文件服务器,头像存哪里合适
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);