Flyway Java 迁移:将 BLOB 插入 Postgresql

Flyway Java Migrations: insert BLOB into Postgresql

我正在使用 Flyway 进行所有数据库迁移。迁移时是时候处理二进制数据(图像)了。我正在使用 Postgresql 和 Spring Data JPA。

首先,我使用 Postgresql

得到了这个字段,导致数据库列 photo oid
@Entity
public class Person {
  // omitted 

  @Lob
  private byte[] photo;
}

我的迁移脚本看起来像这样

V1__CREATE_DB.sql
V2__INSERT_PERSON.sql
V3__INSERT_PHOTO.java

起初我没能使用 JdbcTemplate 成功迁移(更新)一个有照片的人。后来我发现我可以通过这样做将类型oid更改为bytea

@Lob
@Type(type = "org.hibernate.type.BinaryType")
private byte[] photo;

然后我使迁移代码看起来像这样

public void migrate(Context context) throws IOException {
  JdbcTemplate template = ...
  List<String> locations = ... // photo physical locations/paths

  for(String location: locations) {
    InputStream image = ... // from location
    Long id = ... // get id from image name

    template.update("UPDATE person SET photo = ? where id = " + id,
      new Object[] { new SqlLobValue(image.readAllBytes(), new DefaultLobHandler()) },
      new int[] { Types.BLOB }
    );
  }
}

此 V3__ 迁移按预期工作但是

在几乎崩溃 Google 之后,我终于设法找到了如何使用 JdbcTemplate 更新列 photo oid 的解决方案。

DefaultLobHandler lobHandler = new DefaultLobHandler();
lobHandler.setWrapAsLob(true);

jdbcTemplate.execute("UPDATE person SET photo = ? where id = ?", new AbstractLobCreatingPreparedStatementCallback(lobHandler) {                                                       
  protected void setValues(PreparedStatement ps, LobCreator lobCreator) throws SQLException {     
    lobCreator.setBlobAsBinaryStream(ps, 1, image, image.available());                                        
    ps.setLong(2, id);
  }
}