SpringBoot3+Vue3+Mysql+Element Plus完成数据库存储blob类型图片,前端渲染后端传来的base64类型图片

前言

如果你的前后端分离项目采用SpringBoot3+Vue3+Element Plus,且在没有OSS(对象存储)的情况下,使用mysql读写图片(可能不限于图片,待测试)。

耗时三天,在踩了无数雷后,终于完成本功能。为你呈上。

本文完成功能:

  1. 前端采用Element发起上传图片请求,后端接收并将其存储到mysql。
  2. 后端相应图片base64数据,前端接收并渲染到页面。

1.前端上传到数据库

1.1前端上传图片

<el-form-item label="宠物照片" prop="pictureId">
<el-upload v-model="form.pictureId" :auto-upload="false" :action="''" 
           :show-file-list="true" :on-change="handleAvatarChangeIcon">
  <el-button type="primary">选取文件</el-button>
</el-upload>
</el-form-item>

参数:

:auto-upload 是否自动上传

:action 自动上传的请求路径

:show-file-list 显示已上传的图片列表

:on-change 选中文件触发的change事件

自动上传与否都不影响,这里主要是判断一下图片的大小、后缀名。如下:

const handleAvatarChangeIcon = (file) => {
  // 限制文件后缀名
  const isJPG = file.raw.type === 'image/jpeg'
  const isPNG = file.raw.type === 'image/png'
  // 限制上传文件的大小
  const isLt5M = file.raw.size / 1024 / 1024 < 5
  if (!isPNG && !isJPG) {
    ElMessage.error('图片只能是 JPG/PNG 格式')
    return false
  } else if (!isLt5M) {
    ElMessage.error('图片应在5MB以内')
    return false
  } else {
    // 发起请求
    let param = new FormData();
    // 文件为form data格式
    param.append("file", file.raw);
    post('/api/file/upload', param, (res) => {
      ElMessage.success('上传成功');
      // 返回值为图片id
      form.pictureId = res
    })
  }
}

1.2后端接收并保存数据库

controller

@RestController
@RequestMapping("/api/file")
public class FileController {
    @Resource
    private FileService fileService;

    @PostMapping("/upload")
    public RestBean<String> upload(@RequestParam MultipartFile file) {
        Integer res = fileService.upload(file);
        return RestBean.success(String.valueOf(res));
    }
}

serviceImpl

@Service
public class FileServiceImpl implements FileService {
    @Resource
    private FileMapper fileMapper;

    /**
     * 文件上传到数据库
     */
    @Override
    public Integer upload(MultipartFile file) throws IOException {
        // 获取文件原始名
        String originalFilename = file.getOriginalFilename();
        // 获取文件后缀名
        String endName = "png";
        if (originalFilename != null) {
            endName = originalFilename.substring(originalFilename.lastIndexOf("."));
        }
        // 拼接文件名
        String filename = UUID.randomUUID() + endName;
        Integer pictureId;
        // 创建图片对象
        byte[] fileBytes = file.getBytes();
        Picture picture = new Picture();
        picture.setName(filename);
        picture.setPicData(fileBytes);
        // 上传数据库
        fileMapper.upload(picture);
        pictureId = picture.getId();
        // 返回图片id
        return pictureId;
    }
}

mapper.xml

<mapper namespace="com.ycb.mapper.FileMapper">
    <insert id="upload" useGeneratedKeys="true" keyProperty="id">
        insert into `pet-adoption`.picture(name, pic_data)
            value (#{name}, #{picData})
    </insert>
</mapper>

数据库设计

在这里插入图片描述

2.前端从数据库获取图片并渲染

2.1后端从数据库中获取

entity

public class PetAndBulVO {
    /**
     * 照片
     */
    private byte[] picData;
}

controller

如果是一个图片数据直接封装到实体类,很多数据就封装成集合

@RequestMapping("/api/pet")
public class PetController {
    @Resource
    private PetService petService;

    @GetMapping("/getAllPB")
    public RestBean<List<PetAndBulVO>> getAll() {
        List<PetAndBulVO> pets = petService.getAll();
        return RestBean.success(pets);
    }
}

serviceImpl

@Service
public class PetServiceImpl implements PetService {
    @Resource
    private PetMapper petMapper;

    @Override
    public List<PetAndBulVO> getAll() {
        return petMapper.getAll();
    }
}

mapper.xml

<mapper namespace="com.ycb.mapper.PetMapper">
    <!--  一定要映射结果集  -->
    <resultMap type="com.ycb.entity.vo.response.PetAndBulVO" id="petAndBulVO">
        <id column="pic_data" property="picData" javaType="byte[]" jdbcType="BLOB" typeHandler="org.apache.ibatis.type.BlobTypeHandler"/>
    </resultMap>

    <select id="getAll" resultMap="petAndBulVO">
        select *
        from `pet-adoption`.pet pet
                 join `pet-adoption`.picture p on p.id = pet.picture_id
    </select>

后端返回的图片数据如下:

在这里插入图片描述

2.2前端接收数据并渲染

后端传来的数据是 base64 形式的,需要解码

// 解码
const base64ToUrl = (base64) => {
    return 'data:image/png;base64,' + base64
}

// 获取数据
get('/api/pet/getAllPB', (data) => {
  for (let i = 0; i < data.length; i++) {
    data[i].picData = base64ToUrl(data[i].picData)
  }
  pBList.value = data
}, (err) => {
  ElMessage.error(err)
})

解码后的图片数据如下:

在这里插入图片描述

渲染是大坑!一定要 v-bind: 绑定 src

// v-for循环获取picData, v-for="(pb) in pBList"
<el-image v-bind:src="pb.picData"/>

《林克可爱图》
在这里插入图片描述

写在最后

虽然可以实现仅用mysql就能完成图片读写,但其性能堪忧。

很难,但贵在坚持。

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot是一个用于简化Java开发的框架,Vue是一种流行的前端框架,Element Plus是一个基于Vue的UI组件库。要打造一个分布式存储系统,我们可以使用Spring Boot作为后端框架,VueElement Plus作为前端框架。 首先,我们使用Spring Boot搭建后端服务。Spring Boot提供了许多功能,如依赖管理、自动配置和快速开发等。我们可以使用Spring Boot来构建分布式存储系统的后端逻辑,包括数据存储、数据处理和业务逻辑等。Spring Boot还提供了与其他Java框架和技术的集成,如Spring Data、Spring Cloud和Spring Security等,这些可以帮助我们更轻松地构建和管理分布式存储系统。 接下来,我们使用VueElement Plus来构建前端界面。Vue是一个基于JavaScript的前端框架,可以帮助我们构建交互式的用户界面。Element PlusVue的一个组件库,提供了丰富的UI组件和样式。我们可以使用VueElement Plus来创建用户界面,如存储系统的文件上传、文件下载和文件管理等功能。通过VueElement Plus的组合,我们可以快速构建出美观、实用的前端界面。 最后,我们将后端前端进行集成。可以使用Spring Boot的REST API作为后端服务的接口,通过HTTP协议与前端进行通信。前端通过VueElement Plus可以发起请求并接收后端的响应,实现与后端的数据交互和处理。 综上所述,使用Spring Boot、VueElement Plus的组合,我们可以打造一个功能强大的分布式存储系统。Spring Boot提供了后端逻辑的开发框架,VueElement Plus提供了前端界面的构建工具和UI组件。通过它们的协作,我们可以实现分布式存储系统的数据管理、用户界面和数据交互等功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值