Springboot中使用PostgreSQL存取图片时需要注意的事项

简单阐述一下存与取两者之中的一些雷。(主要用Mybatis哈)

存放过程:列的类型设置为"bytea",在JAVA中用byte[]读取。

                 注意SQL语句与常用MYSQL、msSQL之间的差别。(如莫名其妙的单双引号)

                  存放过程中,切记要用“#{}”来作bytea的占位符,而不是用“${}”。(使用#{}是好习惯,可以防止SQL注入攻击。在别的数据库可能体现不出来两者差别,但PostgreSQL很多参数都要用单引号''来标出来,否则执行SQL语句会报错,于是乎存在 '${}' 和 #{} 两种传参方式,生动地说明了什么是直接替换和预编辑。)

在下面两个语句中,如果使用了上者,那么恭喜你,图片大概率完整的存储到数据库中了,但下者则没那么好运了,因为直接替换型传参可能会造成大量字节的丢失,图片直接被破坏了。

        @Insert("INSERT INTO public.\"Image\" (data) VALUES( #{data} )")

        @Insert("INSERT INTO public.\"Image\" (data) VALUES( ${data} )")

                  Java中对应的数据类型为byte[],建议使用MultipartFile file来作上传函数的参数,用file.getBytes()把文件(图片,二进制方式存储的)转换为byte数组。上传图片方式多种多样,我就不赘述了。

        总结:注意语句的设计、注意传参的使用、注意类型的设置。

                   存入后,可以导出数据库中表的内容,来判断有无存储成功。

取出过程:主要讲如何将表中的图片投映到网页中吧。

                  使用注解执行SQL时,注意设计合适的实体类和Mapper接口返回的类型

譬如下面的代码,Image表中的各列我都在实体类中Image中定义了,所以Service调用后搜索结果会自动一一映射到我们实体类Image的(临时)变量中,非常的方便,Controller中可以直接获得。(代码并不完整,只是举例说明实体类和返回类型的设计的便利)

@Select("SELECT * FROM public.\"Image\" ORDER BY upload_date DESC")
Image[] GetImage();
@GetMapping("/image-get")
public List<String> getImage() throws IOException {
    Image[] images = imageService.GetImage();

                  使用byte[]型读取到后端,并且在后端将之转为String型的Base64图片

上述代码之所是String列表而不是byte[]列表,就说明要在后端将数据加工后再传给前端。原因很简单,前端解码效率低,Base64这种好处理太多了。

for (Image image : images) {
    BufferedImage bufferedImage = ImageIO.read(new ByteArrayInputStream(image.getData()));
    String base64Image = imageToBase64(bufferedImage);
    base64Images.add(base64Image);
}

中间转为BufferedImage,是可以帮助我们事先检查一下提取出来的图片是否可以正常显示。返回前端的是base64Images。

                  前端处理。

这部分花样很多,这里给个例子:简单理解就是创建一个图片数组images,在钩子函数中创立一个image实体,包含图像数据本身和新增的URL(因为html中常用img src来载入图片)。使用fetch调用GetMapping,此时会获得一个保留图片数组数据的json文件,遍历它,将每张图片塞入images数组中,并设置每张图片对应的src值。

new Vue({
    el: '#image',
    data() {
        return {
            images: []
        };
    },
    mounted() {
        console.log('mounted 钩子函数被调用,实例已挂载到 DOM');
        fetch('/image-get')
            .then(response => response.json())
            .then(base64Images => {
                for (const base64Image of base64Images) {
                    const img = new Image();
                    img.onload = () => {
                        this.images.push(img);
                    };
                    img.src = 'data:image/jpeg;base64,' + base64Image;
                }
            })
            .catch(error => {
                this.$message.error('图片传输失败');
            });
    }
})
;

那么html就好写了:

<div v-for="image in images" class="image-item">
  <img :src="image.src" >
</div>

之后打开对应网页,不出意外数据库中的图片应该能显现出来了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值