spring-data-jpa存储blob

use*_*745 7 blob spring-data-jpa

使用spring-data-jpa用blob存储实体的“最佳”或规范方法是什么?

@Entity
public class Entity {
  @Id
  private Long id;
  @Lob()
  private Blob blob;
}

public interface Repository extends CrudRepository<Entity,  Long> {
}
Run Code Online (Sandbox Code Playgroud)

Jan*_*yka 10

TL; 博士

您可以在我的github上看到示例项目。该项目显示了如何与数据库之间进行数据流传输。

问题

有关映射的所有建议@Lob作为byte[]流-失败(IMO)斑点的主要优势。随着byte[]一切都加载到内存中。可能行,但如果你去大号 ARGE Ø bject你可能要流。

制图

@Entity
public class MyEntity {

    @Lob
    private Blob data;

    ...

}
Run Code Online (Sandbox Code Playgroud)

组态

公开休眠的SessionFactoryCurrentSession,以便您可以掌握LobCreator。在application.properties中

spring.jpa.properties.hibernate.current_session_context_class=org.springframework.orm.hibernate5.SpringSessionContext
Run Code Online (Sandbox Code Playgroud)

将会话工厂公开为bean:

@Bean // Need to expose SessionFactory to be able to work with BLOBs
public SessionFactory sessionFactory(HibernateEntityManagerFactory hemf) {
    return hemf.getSessionFactory();
}
Run Code Online (Sandbox Code Playgroud)

创建blob

@Service
public class LobHelper {

    private final SessionFactory sessionFactory;

    @Autowired
    public LobHelper(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    public Blob createBlob(InputStream content, long size) {
        return sessionFactory.getCurrentSession().getLobHelper().createBlob(content, size);
    }

    public Clob createClob(InputStream content, long size, Charset charset) {
        return sessionFactory.getCurrentSession().getLobHelper().createClob(new InputStreamReader(content, charset), size);
    }
}
Run Code Online (Sandbox Code Playgroud)

而且-正如评论中指出的-只要您使用@Blob包含流,您就需要参与事务。只需标记工作部分@Transactional


Har*_*udi 6

自动装配您的存储库接口并调用传递实体对象的 save 方法。

我有一个类似的设置,效果很好:

@Autowired
Repository repository;

repository.save(entity);

@Entity
@Table(name = "something")
public class Message {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Lob
    @Column
    private byte[] data;
Run Code Online (Sandbox Code Playgroud)

  • 这违背了流式传输的目的,您可能会遇到更大数据的 OOM。 (3认同)

Pau*_*ren 5

Spring Data 不处理 BLOB,但Spring Content可以。具体来说,Spring Content JPA 将内容作为 BLOB 存储在数据库中,并通过注解将该内容与实体相关联。

pom.xml

   <!-- Java API -->
   <dependency>
      <groupId>com.github.paulcwarren</groupId>
      <artifactId>spring-content-jpa-boot-starter</artifactId>
      <version>0.0.11</version>
   </dependency>
   <!-- REST API -->
   <dependency>
      <groupId>com.github.paulcwarren</groupId>
      <artifactId>spring-content-rest-boot-starter</artifactId>
      <version>0.0.11</version>
   </dependency>
Run Code Online (Sandbox Code Playgroud)

实体.java

@Entity
public class Entity {
   @Id
   @GeneratedValue
   private long id;

   @ContentId
   private String contentId;

   @ContentLength
   private long contentLength = 0L;

   // if you have rest endpoints
   @MimeType
   private String mimeType = "text/plain";
Run Code Online (Sandbox Code Playgroud)

数据内容存储库

@StoreRestResource(path="data")
public interface DataContentStore extends ContentStore<Data, String> {
}
Run Code Online (Sandbox Code Playgroud)

这种方法相对于已接受答案的优势在于,开发人员无需担心任何样板代码(已接受答案中的“服务”)。BLOB 也作为 Spring Resource 公开,提供自然的编程接口。或者可以通过 REST 接口自动导出。但是,除了 java 配置和商店界面之外,这一切都不需要任何编码,代表开发人员。