Tôi đã giải quyết được vấn đề nhờ câu trả lời @gvenzi, nhưng quyết định đăng câu trả lời của riêng tôi vì tôi có một số nhận xét bổ sung.
Vì vậy, có, OracleLobHandler
giải quyết vấn đề. Nhưng trên thực tế, chúng ta không buộc phải sử dụng lớp không được chấp nhận. Trong OracleLobHandler tài liệu
Tôi đã tìm thấy
Tôi đã thử nghiệm nó và nó hoạt động.
Nhưng tôi gặp sự cố khác khi sử dụng SqlLobValue
cùng với OracleTypes.BLOB
trong PreparedStatementSetter
(nó được mô tả ở đây ClassCastException:Không thể truyền SqlLobValue sang oracle.sql.BLOB bằng PreparedStatementSetter
)
Mã làm việc cuối cùng của tôi như sau:
public void saveThumbnails(List<Thumbnail> fileList) throws SQLException, IOException {
BatchPreparedStatementSetter b = new BatchPreparedStatementSetter() {
@Override
public void setValues(PreparedStatement ps, int i) throws SQLException {
Thumbnail thumbnail = fileList.get(i);
byte[] thumbnailBytes = thumbnail.getThumbnail();
ps.setObject(1, thumbnail.getFileCId(), OracleTypes.NUMBER);
ps.setObject(2, thumbnail.getType().toString(), OracleTypes.VARCHAR);
DefaultLobHandler lobHandler = new DefaultLobHandler();
lobHandler.setCreateTemporaryLob(true);
lobHandler.getLobCreator().setBlobAsBytes(ps, 3, thumbnailBytes);
}
@Override
public int getBatchSize() {
return fileList.size();
}
};
jdbcTemplate.batchUpdate(getSaveThumbnailSql(), b);
}
private String getSaveThumbnailSql() {
// @formatter:off
String sql = ""
+ "MERGE INTO file_thumbnails "
+ " USING (SELECT ? as file_c_id, ? as thumbnail_type, ? AS thumbnail_image FROM DUAL) tmp "
+ " ON (file_thumbnails.file_c_id = tmp.file_c_id AND "
+ " file_thumbnails.thumbnail_type = tmp.thumbnail_type) "
+ " WHEN MATCHED THEN "
+ " UPDATE "
+ " SET thumbnail_image = tmp.thumbnail_image"
+ " ,thumbnail_date = SYSDATE "
+ " WHEN NOT MATCHED THEN "
+ " INSERT (c_id, file_c_id, thumbnail_type, thumbnail_image, thumbnail_date) "
+ " VALUES (cedar_c_id_seq.nextval, tmp.file_c_id, tmp.thumbnail_type, tmp.thumbnail_image , SYSDATE)";
//@formatter:on
return sql;
}