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__ 迁移按预期工作但是
是否有更好的方法来实现此迁移,我是否也可以为 oid
执行此操作,在那种情况下如何?
除了明显的存储容量差异之外,还有什么理由不选择 bytea
而不是 oid
?
在几乎崩溃 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);
}
}
我正在使用 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__ 迁移按预期工作但是
是否有更好的方法来实现此迁移,我是否也可以为
oid
执行此操作,在那种情况下如何?除了明显的存储容量差异之外,还有什么理由不选择
bytea
而不是oid
?
在几乎崩溃 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);
}
}