Spring的数据存储JPA BLOB

问题描述 投票:6回答:5

什么是用弹簧数据的JPA存储与BLOB实体“最佳”或规范的方法?

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

public interface Repository extends CrudRepository<Entity,  Long> {
}
blob spring-data-jpa
5个回答
9
投票

TL; DR

你可以看到sample project on my github。该项目展示了如何从数据库流数据/。

问题

流 - 关于映射@Lobbyte[]击败(IMO)的主要优势斑点的所有建议。随着byte[]一切都被加载到内存中。可能行,但如果你有LargeObject去,你可能要流。

Mapping

@Entity
public class MyEntity {

    @Lob
    private Blob data;

    ...

}

Configuration

暴露的SessionFactory和CurrentSession这样你就可以得到LobCreator的保持。在application.properties:

spring.jpa.properties.hibernate.current_session_context_class=org.springframework.orm.hibernate5.SpringSessionContext

暴露会话工厂的bean:

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

Create 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);
    }
}

此外 - 在评论中指出的 - 只要你与@Blob包括你得到你需要的事务中的流工作。只要勾选工作部分@Transactional


4
投票

春天的数据不处理的BLOB但Spring Content一样。具体来说,春天内容JPA存储内容,如数据库和内容与实体通过注释同事的BLOB。

pom.hml

   <!-- 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>

entity.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";

data content store.Java

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

这种方法在接受答案的优势在于,开发者不需要担心任何的样板代码(在接受的答案“服务”)的。斑也暴露春天资源给人一种自然的编程接口。或者,可以通过REST接口自动导出。但是,这一切都不需要任何编码,代表开发的,除了Java的配置和商店界面。


2
投票

自动装配资源库接口,并呼吁通过你的实体对象的保存方法。

我有一个类似的设置它工作得很好:

@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;

1
投票

您可以使用Hibernate.getLobCreator和传递一个EntityManager的能解开你的会话一条语句(低于4)做到这一点:

// 1. Get entity manager and repository
EntityManager em = .... // get/inject someway the EntityManager
EntityRepository repository = ...// get/inject your Entity repository

// 2. Instantiate your Entity
Entity entity = new Entity();

// 3. Get an input stream (you shall also know its length)
File inFile = new File("/somepath/somefile");
InputStream inStream = new FileInputStream(inFile);

// 4. Now copy to the BLOB
Blob blob =
  Hibernate.getLobCreator(em.unwrap(Session.class))
           .createBlob(inStream, inFile.length());

// 5. And finally save the BLOB
entity.setBlob(blob);
entityRepository.save(f);

0
投票

您也可以从Blob创建DataSource权:

@Component
public class LobHelper {

    private final DataSource ds;

    public LobHelper(@Autowired DataSource ds){
         this.ds = ds;
    }

    public Blob createBlob(byte[] content) {
        try (Connection conn = ds.getConnection()) {
            Blob b = conn.createBlob();
            try (OutputStream os = b.setBinaryStream(1);
                 InputStream is = new ByteArrayInputStream(content)) {
                byte[] buffer = new byte[500000];
                int len;
                while ((len = is.read(buffer)) > 0) {
                    os.write(buffer, 0, len);
                }
                return b;
            }
        } catch (Exception e) {
            log.error("Error while creating blob.", e);
        }
        return null;
    }

}
© www.soinside.com 2019 - 2024. All rights reserved.