【问题标题】:How to write java.sql.Blob to JPA entity?如何将 java.sql.Blob 写入 JPA 实体?
【发布时间】:2011-06-29 05:31:31
【问题描述】:

我有一个带有 java.sql.Blob 的 JPA 实体:

@Entity
public class LargeData {

  @Lob
  private java.sql.Blob data;

  //getters/setters
}

如何创建这个实体的实例?我想用setData() 方法设置Blob,但是如何从JPA 获取Blobjava.sql.Blob 只是接口,不同的数据库有不同的实现,所以我认为 JPA 应该给我正确的实现。如何获得?

【问题讨论】:

    标签: java jpa blob


    【解决方案1】:

    使用字节数组:

    @Lob
    @Column(length=100000)
    private byte[] data;
    

    如果您想使用流,请使用 Hibernate.createBlob(..) 创建 blob

    【讨论】:

    • 已接受答案的附加信息。 2016年亲身经历证实。stackoverflow.com/a/16599953/102658tl;dr:>length属性用于定义String字段的>列长度(其他类型忽略
    • 这对我来说使用的是 clob,而不是 blob。
    • 我没有指定length 属性。我还使用 java nio 从文件中读取:myEntity.data = Files.readAllBytes(myPath).
    【解决方案2】:

    使用文件流。 但是,这似乎有各种复杂性,具体取决于您的数据库、驱动程序和 JPA 实现。 我构建了一个通用解决方案,速度很慢,并且在处理大文件时失败,然后找到了一个适用于 Oracle 11.2.0.4 的 Hibernate 特定解决方案

    我正在使用 Spring Data / JPA,但问题似乎与 Hibernate 相关,而不是 Spring。

    休眠:

    private void testLoadFile() throws SQLException, IOException {
    
    
      File f = new File("//C:/tmp/6mb_file.wmv");
      BufferedInputStream fstream = new BufferedInputStream(new FileInputStream(f));
    
      Session session = entityManager.unwrap(Session.class);
      Blob blob = Hibernate.getLobCreator(session).createBlob(fstream, f.length());
    
      FileBLOBEntity file = new FileBLOBEntity();
    
      file.setName("//C:/tmp/6mb_file.wmv");
      file.setTheData(blob);
      blobRepository.saveAndFlush(file);
    }
    

    通用 Spring/JPA:

    private void testLoadFile() throws SQLException, IOException {
    
      File f = new File("//C:/tmp/6mb_file.wmv");
      BufferedInputStream fstream = new BufferedInputStream(new FileInputStream(f));
    
      Blob blob = connection.getConnection().createBlob();
      BufferedOutputStream bstream = new  BufferedOutputStream(blob.setBinaryStream(1));
      // stream copy runs a high-speed upload across the network
      StreamUtils.copy(fstream, bstream);
    
      FileBLOBEntity file = new FileBLOBEntity();
    
      file.setName("//C:/tmp/6mb_file.wmv");
      file.setTheData(blob);
      // save runs a low-speed download across the network.  this is where
      // Spring does the SQL insert.  For a large file, I get an OutOfMemory exception here.
      blobRepository.saveAndFlush(file);
    }
    

    用于检索:

    public void unloadFile() throws SQLException, IOException {
    
      File f = new File("//C:/tmp/6mb_file.wmv" + "_fromDb");
    
      FileOutputStream fstream = new FileOutputStream(f);
    
      FileBLOBEntity file = blobRepository.findByName("//C:/tmp/6mb_file.wmv");
      Blob data = file.getTheData();
    
      InputStream bstream = data.getBinaryStream();
      StreamUtils.copy(bstream, fstream);
    
    }
    

    【讨论】:

    • 有效,但特定于 Hibernate,如果您使用 EclipseLink,它会中断
    • ... 我在帖子顶部说明了这一点。我不喜欢特定于实现,但这是我发现的唯一一个既稳定又足够快的解决方案。
    猜你喜欢
    • 2015-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-10
    • 2011-01-20
    • 1970-01-01
    • 2020-01-20
    相关资源
    最近更新 更多