使用 BLOB 类型将图像存储在数据库中

Posted

技术标签:

【中文标题】使用 BLOB 类型将图像存储在数据库中【英文标题】:Storing Images in database with BLOB type 【发布时间】:2020-09-03 00:00:58 【问题描述】:

我有一个问题。如何将文件保存在数据库中?我将 Spring Boot 用于后端语言和 PostgreSQL 数据库。我有一个用户实体,并且有“头像”字段:

@Lob
@Column(name = "avatar", columnDefinition="BLOB")
private byte[] avatar;

@Lob
@Basic(fetch = FetchType.LAZY)
public byte[] getAvatar() 
   return avatar;

public void setAvatar(byte[] avatar) 
   this.avatar = avatar;

当我第一次注册用户时,头像为 null,当我将用户保存到数据库时,我收到错误 (InvalidDataAccessResourceUsageException) 并且此消息:错误:列“头像”的类型为 jsonb但表达式的类型是 oid 提示:您将需要重写或强制转换表达式。 位置:173 我该怎么做才能解决这个问题? Spring是如何解决这个问题并将文件保存在DB中的? 最佳做法是什么?

【问题讨论】:

看起来 DB 方案的类型为 jsonb。您在 db 控制台中使用 \d 看到了什么 我看到了jsonb格式 这就是为什么你不能在其中写入 blob。 我该如何解决? 【参考方案1】:

你应该看看社区项目Spring Content。该项目为您提供了一个类似于 Spring Data 的 API 和内容开发方法。它是非结构化数据(文档、图像、视频等),Spring Data 是结构化数据。您可以使用以下内容添加它:-

pom.xml(也可以使用 Spring Boot 启动器)

   <!-- Java API -->
   <dependency>          
      <groupId>com.github.paulcwarren</groupId>
      <artifactId>spring-content-jpa</artifactId>
      <version>1.0.0.M10</version>
   </dependency>
   <!-- REST API -->
   <dependency>
      <groupId>com.github.paulcwarren</groupId>
      <artifactId>spring-content-rest</artifactId>
      <version>1.0.0.M10</version>
   </dependency>

配置

@Configuration
// enables Java API 
@EnableJpaStores
// enables REST API 
@Import("org.springframework.content.rest.config.RestConfiguration.class") 
public class ContentConfig 

   // specify the resource specific to your database
   @Value("/org/springframework/content/jpa/schema-drop-postgresql.sql")
   private ClasspathResource dropBlobTables;

   // specify the resource specific to your database
   @Value("/org/springframework/content/jpa/schema-postgresql.sql")
   private ClasspathResource createBlobTables;

   @Bean
   DataSourceInitializer datasourceInitializer() 
     ResourceDatabasePopulator databasePopulator =
            new ResourceDatabasePopulator();

     databasePopulator.addScript(dropBlobTables);
     databasePopulator.addScript(createBlobTables);
     databasePopulator.setIgnoreFailedDrops(true);

     DataSourceInitializer initializer = new DataSourceInitializer();
     initializer.setDataSource(dataSource());
     initializer.setDatabasePopulator(databasePopulator);

     return initializer;
   

注意:如果您使用相关的 Spring Boot 启动器,则不需要此配置。

要关联内容,请将 Spring Content 注释添加到您的 User 实体。

用户.java

@Entity
public class User 

   ...

   // replace @Lob/byte array field with:

   @ContentId
   private String contentId;
    
   @ContentLength
   private long contentLength = 0L;
    
   @MimeType
   private String mimeType;

为您的图片创建头像“商店”:

AvatarStore.java

public interface AvatarStore extends ContentStore<User, String> 

这就是创建响应内容类型的 REST 端点 @/users/userId 所需的全部内容。当您的应用程序启动时,Spring Content 将查看您的依赖项(查看 Spring Content JPA/REST),查看您的 AvatarStore 接口并为 JPA 注入该接口的实现。它还将注入一个@Controller,将http请求转发到该实现。这使您不必自己实现任何这些。

所以...

curl -X POST /users/userId -F 'file=@path/to/local/file.jpg'

会将头像path/to/local/file.jpg存储在数据库中,并将其与ID为userId的User实体关联。

curl /users/usersId -H 'Accept: image/jpg'

将再次获取它,依此类推...支持完整的 CRUD(顺便说一句,视频流也支持)

有入门指南和视频here。 Spring Content JPA 的参考指南是here。

HTH

【讨论】:

有没有其他方法可以做到这一点,因为如果我选择这个变体我会改变很多代码。

以上是关于使用 BLOB 类型将图像存储在数据库中的主要内容,如果未能解决你的问题,请参考以下文章

将图像作为数据 URI 存储在数据库 BLOB 中是否很糟糕?

将存储在数据库中的 BLOB 转换为 HTML 网站上的图像

ORACLE SQL中获取BLOB的图像格式

哪种数据类型最适合将图像保存在数据库中?

如何查询blob类型中存的是啥格式的文件

显示存储为 MySQL 数据库中 BLOB 数据的所有图像